@@ -105,6 +105,8 @@ struct ul_opts {
105105 int new_port ;
106106
107107 int onhold ;
108+ int tos ;
109+ int has_tos ;
108110};
109111
110112#define BC_appendf (f , ...) { \
@@ -181,6 +183,8 @@ ul_opts_init(const struct rtpp_cfg *cfsp, struct ul_opts *ulop)
181183 ulop -> lia [0 ] = ulop -> lia [1 ] = ulop -> reply .ia = cfsp -> bindaddr [0 ];
182184 ulop -> lidx = 1 ;
183185 ulop -> pf = AF_INET ;
186+ ulop -> tos = -1 ;
187+ ulop -> has_tos = 0 ;
184188}
185189
186190void
@@ -366,6 +370,30 @@ rtpp_command_ul_opts_parse(const struct rtpp_cfg *cfsp, struct rtpp_command *cmd
366370 ulop -> new_port = 1 ;
367371 break ;
368372
373+ case 't' :
374+ case 'T' : {
375+ const char * next , * vsp ;
376+ enum atoi_rval arval ;
377+ long ntos ;
378+
379+ vsp = cp + 1 ;
380+ if (!isdigit ((unsigned char )* vsp )) {
381+ RTPP_LOG (cmd -> glog , RTPP_LOG_ERR , "command syntax error" );
382+ CALL_SMETHOD (cmd -> reply , deliver_error , ECODE_INVLARG_8 );
383+ goto err_undo_1 ;
384+ }
385+ arval = strtol_saferange (vsp , & ntos , 0 , 255 , & next );
386+ if (arval != ATOI_OK ) {
387+ RTPP_LOG (cmd -> glog , RTPP_LOG_ERR , "command syntax error" );
388+ CALL_SMETHOD (cmd -> reply , deliver_error , ECODE_INVLARG_8 );
389+ goto err_undo_1 ;
390+ }
391+ ulop -> tos = (int )ntos ;
392+ ulop -> has_tos = 1 ;
393+ cp = (char * )next - 1 ;
394+ break ;
395+ }
396+
369397 default :
370398 RTPP_LOG (cmd -> glog , RTPP_LOG_ERR , "unknown command modifier `%c'" ,
371399 * cp );
@@ -442,6 +470,7 @@ rtpp_command_ul_handle(const struct rtpp_cfg *cfsp, struct rtpp_command *cmd, in
442470 struct rtpp_session * spa , * spb ;
443471 struct rtpp_socket * fd ;
444472 struct ul_opts * ulop ;
473+ int desired_tos ;
445474
446475 pidx = 1 ;
447476 lport = 0 ;
@@ -460,14 +489,16 @@ rtpp_command_ul_handle(const struct rtpp_cfg *cfsp, struct rtpp_command *cmd, in
460489 if (sidx != -1 ) {
461490 RTPP_DBG_ASSERT (cmd -> cca .op == UPDATE || cmd -> cca .op == LOOKUP );
462491 spa = cmd -> sp ;
492+ desired_tos = ulop -> has_tos ? ulop -> tos : spa -> rtp -> stream [sidx ]-> tos ;
463493 fd = CALL_SMETHOD (spa -> rtp -> stream [sidx ], get_skt , HEREVAL );
464494 if (fd == NULL || ulop -> new_port != 0 ) {
465495 if (ulop -> local_addr != NULL ) {
466496 spa -> rtp -> stream [sidx ]-> laddr = ulop -> local_addr ;
467497 } else if (ulop -> new_port != 0 && ulop -> lidx == -1 && spa -> rtp -> stream [sidx ]-> laddr != ulop -> lia [0 ]) {
468498 spa -> rtp -> stream [sidx ]-> laddr = ulop -> lia [0 ];
469499 }
470- if (rtpp_create_listener (cfsp , spa -> rtp -> stream [sidx ]-> laddr , & lport , fds ) == -1 ) {
500+ if (rtpp_create_listener (cfsp , spa -> rtp -> stream [sidx ]-> laddr , & lport , fds ,
501+ desired_tos ) == -1 ) {
471502 if (fd != NULL )
472503 RTPP_OBJ_DECREF (fd );
473504 RTPP_LOG (spa -> log , RTPP_LOG_ERR , "can't create listener" );
@@ -487,6 +518,8 @@ rtpp_command_ul_handle(const struct rtpp_cfg *cfsp, struct rtpp_command *cmd, in
487518 RTPP_OBJ_DECREF (fds [1 ]);
488519 spa -> rtp -> stream [sidx ]-> port = lport ;
489520 spa -> rtcp -> stream [sidx ]-> port = lport + 1 ;
521+ spa -> rtp -> stream [sidx ]-> tos = desired_tos ;
522+ spa -> rtcp -> stream [sidx ]-> tos = desired_tos ;
490523 if (spa -> complete == 0 ) {
491524 rtpp_command_get_stats (cmd )-> nsess_complete .cnt ++ ;
492525 CALL_SMETHOD (spa -> rtp -> stream [0 ]-> ttl , reset_with ,
@@ -495,6 +528,25 @@ rtpp_command_ul_handle(const struct rtpp_cfg *cfsp, struct rtpp_command *cmd, in
495528 cfsp -> max_ttl );
496529 }
497530 spa -> complete = 1 ;
531+ } else if (ulop -> has_tos ) {
532+ if (spa -> rtp -> stream [sidx ]-> laddr -> sa_family == AF_INET ) {
533+ if (CALL_SMETHOD (fd , settos , desired_tos ) == -1 ) {
534+ RTPP_ELOG (spa -> log , RTPP_LOG_ERR ,
535+ "unable to set TOS to %d" , desired_tos );
536+ }
537+ }
538+ struct rtpp_socket * rtcp_fd = CALL_SMETHOD (spa -> rtcp -> stream [sidx ], get_skt , HEREVAL );
539+ if (rtcp_fd != NULL ) {
540+ if (spa -> rtcp -> stream [sidx ]-> laddr -> sa_family == AF_INET ) {
541+ if (CALL_SMETHOD (rtcp_fd , settos , desired_tos ) == -1 ) {
542+ RTPP_ELOG (spa -> log , RTPP_LOG_ERR ,
543+ "unable to set TOS to %d" , desired_tos );
544+ }
545+ }
546+ RTPP_OBJ_DECREF (rtcp_fd );
547+ }
548+ spa -> rtp -> stream [sidx ]-> tos = desired_tos ;
549+ spa -> rtcp -> stream [sidx ]-> tos = desired_tos ;
498550 }
499551 if (fd != NULL ) {
500552 RTPP_OBJ_DECREF (fd );
@@ -541,7 +593,8 @@ rtpp_command_ul_handle(const struct rtpp_cfg *cfsp, struct rtpp_command *cmd, in
541593 CALL_SMETHOD (cmd -> reply , deliver_error , cfsp -> overload_prot .ecode );
542594 goto err_undo_0 ;
543595 }
544- if (rtpp_create_listener (cfsp , ulop -> lia [0 ], & lport , fds ) == -1 ) {
596+ desired_tos = ulop -> has_tos ? ulop -> tos : -1 ;
597+ if (rtpp_create_listener (cfsp , ulop -> lia [0 ], & lport , fds , desired_tos ) == -1 ) {
545598 RTPP_LOG (cmd -> glog , RTPP_LOG_ERR , "can't create listener" );
546599 CALL_SMETHOD (cmd -> reply , deliver_error , ECODE_LSTFAIL_2 );
547600 goto err_undo_0 ;
@@ -559,6 +612,11 @@ rtpp_command_ul_handle(const struct rtpp_cfg *cfsp, struct rtpp_command *cmd, in
559612 handle_nomem (cmd , ECODE_NOMEM_4 , NULL );
560613 return (-1 );
561614 }
615+ int effective_tos = ulop -> has_tos ? ulop -> tos : cfsp -> tos ;
616+ for (int i = 0 ; i < 2 ; i ++ ) {
617+ spa -> rtp -> stream [i ]-> tos = effective_tos ;
618+ spa -> rtcp -> stream [i ]-> tos = effective_tos ;
619+ }
562620
563621 rtpp_command_get_stats (cmd )-> nsess_created .cnt ++ ;
564622
0 commit comments