Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 61661) +++ channels/chan_sip.c (working copy) @@ -511,6 +511,10 @@ #define DEFAULT_TOS_AUDIO 0 /*!< Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions. */ #define DEFAULT_TOS_VIDEO 0 /*!< Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions. */ #define DEFAULT_TOS_TEXT 0 /*!< Text packets should be marked as XXXX XXXX, but the default is 0 to be compatible with previous versions. */ +#define DEFAULT_COS_SIP 4 +#define DEFAULT_COS_AUDIO 5 +#define DEFAULT_COS_VIDEO 6 +#define DEFAULT_COS_TEXT 0 #define DEFAULT_ALLOW_EXT_DOM TRUE #define DEFAULT_REALM "asterisk" #define DEFAULT_NOTIFYRINGING TRUE @@ -565,6 +569,10 @@ static unsigned int global_tos_audio; /*!< IP type of service for audio RTP packets */ static unsigned int global_tos_video; /*!< IP type of service for video RTP packets */ static unsigned int global_tos_text; /*!< IP type of service for text RTP packets */ +static unsigned int global_cos_sip; /*!< 802.1p class of service for SIP packets */ +static unsigned int global_cos_audio; /*!< 802.1p class of service for audio RTP packets */ +static unsigned int global_cos_video; /*!< 802.1p class of service for video RTP packets */ +static unsigned int global_cos_text; /*!< 802.1p class of service for text RTP packets */ static int compactheaders; /*!< send compact sip headers */ static int recordhistory; /*!< Record SIP history. Off by default */ static int dumphistory; /*!< Dump history to verbose before destroying SIP dialog */ @@ -4602,12 +4610,12 @@ } ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); - ast_rtp_settos(p->rtp, global_tos_audio); + ast_rtp_setqos(p->rtp, global_tos_audio, global_cos_audio); ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); if (p->vrtp) { - ast_rtp_settos(p->vrtp, global_tos_video); + ast_rtp_setqos(p->vrtp, global_tos_video, global_cos_video); ast_rtp_setdtmf(p->vrtp, 0); ast_rtp_setdtmfcompensate(p->vrtp, 0); ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); @@ -4615,12 +4623,12 @@ ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); } if (p->trtp) { - ast_rtp_settos(p->trtp, global_tos_text); + ast_rtp_setqos(p->trtp, global_tos_text, global_cos_text); ast_rtp_setdtmf(p->trtp, 0); ast_rtp_setdtmfcompensate(p->trtp, 0); } if (p->udptl) - ast_udptl_settos(p->udptl, global_tos_audio); + ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio); p->maxcallbitrate = default_maxcallbitrate; } @@ -11007,6 +11015,11 @@ ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); ast_cli(fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); + ast_cli(fd, " 802.1p CoS SIP: %d\n", global_cos_sip); + ast_cli(fd, " 802.1p CoS RTP audio: %d\n", global_cos_audio); + ast_cli(fd, " 802.1p CoS RTP video: %d\n", global_cos_video); + ast_cli(fd, " 802.1p CoS RTP text: %d\n", global_cos_text); + ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); @@ -16973,6 +16986,11 @@ global_tos_audio = DEFAULT_TOS_AUDIO; global_tos_video = DEFAULT_TOS_VIDEO; global_tos_text = DEFAULT_TOS_TEXT; + global_cos_sip = DEFAULT_COS_SIP; + global_cos_audio = DEFAULT_COS_AUDIO; + global_cos_video = DEFAULT_COS_VIDEO; + global_cos_text = DEFAULT_COS_TEXT; + externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ externexpire = 0; /* Expiration for DNS re-issuing */ externrefresh = 10; @@ -17258,16 +17276,24 @@ registry_count++; } else if (!strcasecmp(v->name, "tos_sip")) { if (ast_str2tos(v->value, &global_tos_sip)) - ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); + ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-qos.tex.\n", v->lineno); } else if (!strcasecmp(v->name, "tos_audio")) { if (ast_str2tos(v->value, &global_tos_audio)) - ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); + ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-qos.tex.\n", v->lineno); } else if (!strcasecmp(v->name, "tos_video")) { if (ast_str2tos(v->value, &global_tos_video)) - ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); + ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-qos.tex.\n", v->lineno); } else if (!strcasecmp(v->name, "tos_text")) { if (ast_str2tos(v->value, &global_tos_text)) - ast_log(LOG_WARNING, "Invalid tos_text value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); + ast_log(LOG_WARNING, "Invalid tos_text value at line %d, recommended value is 'af41'. See doc/ip-qos.tex.\n", v->lineno); + } else if (!strcasecmp(v->name, "cos_sip")) { + ast_str2cos(v->value, &global_cos_sip); + } else if (!strcasecmp(v->name, "cos_audio")) { + ast_str2cos(v->value, &global_cos_audio); + } else if (!strcasecmp(v->name, "cos_video")) { + ast_str2cos(v->value, &global_cos_video); + } else if (!strcasecmp(v->name, "cos_text")) { + ast_str2cos(v->value, &global_cos_text); } else if (!strcasecmp(v->name, "bindport")) { if (sscanf(v->value, "%d", &ourport) == 1) { bindaddr.sin_port = htons(ourport); @@ -17436,9 +17462,14 @@ ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) - ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); + ast_log(LOG_WARNING, "SIP unable to set TOS to %s\n", ast_tos2str(global_tos_sip)); else if (option_verbose > 1) - ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); + ast_verbose(VERBOSE_PREFIX_2 "SIP using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); + + if (setsockopt(sipsock, SOL_SOCKET, SO_PRIORITY, &global_cos_sip, sizeof(global_cos_sip))) + ast_log(LOG_WARNING, "SIP unable to set CoS to %d\n", global_cos_sip); + else if (option_verbose > 1) + ast_verbose(VERBOSE_PREFIX_2 "SIP using CoS: %d\n", global_cos_sip); } } } Index: channels/iax2-provision.c =================================================================== --- channels/iax2-provision.c (revision 61661) +++ channels/iax2-provision.c (working copy) @@ -332,7 +332,7 @@ ast_log(LOG_WARNING, "Ignoring invalid codec '%s' for '%s' at line %d\n", v->value, s, v->lineno); } else if (!strcasecmp(v->name, "tos")) { if (ast_str2tos(v->value, &cur->tos)) - ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.\n", v->lineno); + ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-qos.tex for more information.\n", v->lineno); } else if (!strcasecmp(v->name, "user")) { strncpy(cur->user, v->value, sizeof(cur->user) - 1); if (strcmp(cur->user, v->value)) Index: channels/chan_iax2.c =================================================================== --- channels/chan_iax2.c (revision 61661) +++ channels/chan_iax2.c (working copy) @@ -9047,7 +9047,7 @@ tosval = ast_variable_retrieve(cfg, "general", "tos"); if (tosval) { if (ast_str2tos(tosval, &tos)) - ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); + ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-qos.tex for more information.\n"); } while(v) { if (!strcasecmp(v->name, "bindport")){ @@ -9222,7 +9222,7 @@ ast_context_create(NULL, regcontext, "IAX2"); } else if (!strcasecmp(v->name, "tos")) { if (ast_str2tos(v->value, &tos)) - ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); + ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-qos.tex for more information.'\n", v->lineno); } else if (!strcasecmp(v->name, "accountcode")) { ast_copy_string(accountcode, v->value, sizeof(accountcode)); } else if (!strcasecmp(v->name, "mohinterpret")) { Index: doc/asterisk.tex =================================================================== --- doc/asterisk.tex (revision 61661) +++ doc/asterisk.tex (working copy) @@ -45,7 +45,7 @@ \subsection{Extensions} \input{extensions.tex} \subsection{IP Type of Service} - \input{ip-tos.tex} + \input{ip-qos.tex} \subsection{MP3 Support} \input{mp3.tex} \subsection{ICES} Index: include/asterisk/acl.h =================================================================== --- include/asterisk/acl.h (revision 61661) +++ include/asterisk/acl.h (working copy) @@ -57,6 +57,9 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us); int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr); + +int ast_str2cos(const char *value, unsigned int *cos); + int ast_str2tos(const char *value, unsigned int *tos); const char *ast_tos2str(unsigned int tos); Index: include/asterisk/rtp.h =================================================================== --- include/asterisk/rtp.h (revision 61661) +++ include/asterisk/rtp.h (working copy) @@ -167,7 +167,7 @@ int ast_rtp_sendcng(struct ast_rtp *rtp, int level); -int ast_rtp_settos(struct ast_rtp *rtp, int tos); +int ast_rtp_setqos(struct ast_rtp *rtp, int tos, int cos); /*! \brief Setting RTP payload types from lines in a SDP description: */ void ast_rtp_pt_clear(struct ast_rtp* rtp); Index: include/asterisk/udptl.h =================================================================== --- include/asterisk/udptl.h (revision 61661) +++ include/asterisk/udptl.h (working copy) @@ -73,7 +73,7 @@ int ast_udptl_fd(struct ast_udptl *udptl); -int ast_udptl_settos(struct ast_udptl *udptl, int tos); +int ast_udptl_setqos(struct ast_udptl *udptl, int tos, int cos); void ast_udptl_set_m_type(struct ast_udptl* udptl, int pt); Index: main/acl.c =================================================================== --- main/acl.c (revision 61661) +++ main/acl.c (working copy) @@ -278,6 +278,20 @@ { "EF", 0x2E }, }; +int ast_str2cos(const char *value, unsigned int *cos) +{ + int fval; + + if (sscanf(value, "%d", &fval) == 1) { + if (fval < 8) { + *cos = fval; + return 0; + } + } + + return -1; +} + int ast_str2tos(const char *value, unsigned int *tos) { int fval; Index: main/rtp.c =================================================================== --- main/rtp.c (revision 61661) +++ main/rtp.c (working copy) @@ -2044,12 +2044,16 @@ return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia); } -int ast_rtp_settos(struct ast_rtp *rtp, int tos) +int ast_rtp_setqos(struct ast_rtp *rtp, int tos, int cos) { int res; if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) - ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); + ast_log(LOG_WARNING, "RTP unable to set TOS to %d\n", tos); + + if ((res = setsockopt(rtp->s, SOL_SOCKET, SO_PRIORITY, &cos, sizeof(cos)))) + ast_log(LOG_WARNING, "RTP unable to set CoS to %d\n", cos); + return res; } Index: main/udptl.c =================================================================== --- main/udptl.c (revision 61661) +++ main/udptl.c (working copy) @@ -872,12 +872,16 @@ return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia); } -int ast_udptl_settos(struct ast_udptl *udptl, int tos) +int ast_udptl_setqos(struct ast_udptl *udptl, int tos, int cos) { int res; - if ((res = setsockopt(udptl->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) + if ((res = setsockopt(udptl->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) ast_log(LOG_WARNING, "UDPTL unable to set TOS to %d\n", tos); + + if ((res = setsockopt(udptl->fd, SOL_SOCKET, SO_PRIORITY, &cos, sizeof(cos)))) + ast_log(LOG_WARNING, "UDPTL unable to set CoS to %d\n", cos); + return res; } Index: configs/sip.conf.sample =================================================================== --- configs/sip.conf.sample (revision 61661) +++ configs/sip.conf.sample (working copy) @@ -57,11 +57,16 @@ ; and multiline formatted headers for strict ; SIP compatibility (defaults to "no") -; See doc/README.tos for a description of these parameters. +; See doc/ip-qos.tex for a description of these parameters. ;tos_sip=cs3 ; Sets TOS for SIP packets. ;tos_audio=ef ; Sets TOS for RTP audio packets. ;tos_video=af41 ; Sets TOS for RTP video packets. +;cos_sip=4 ; Sets CoS for SIP packets. +;cos_audio=6 ; Sets CoS for RTP audio packets. +;cos_video=5 ; Sets CoS for RTP video packets. +;cos_text=0 ; Sets CoS for RTP text packets. + ;maxexpiry=3600 ; Maximum allowed time of incoming registrations ; and subscriptions (seconds) ;minexpiry=60 ; Minimum length of registrations/subscriptions (default 60)