Changeset 2538
- Timestamp:
- Mar 23, 2009 1:14:26 PM (16 years ago)
- Location:
- pjproject/branches/1.0
- Files:
-
- 6 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/1.0
- Property svn:mergeinfo changed
/pjproject/trunk merged: 2505,2522
- Property svn:mergeinfo changed
-
pjproject/branches/1.0/pjlib-util/src/pjlib-util/scanner.c
r2394 r2538 29 29 #define PJ_SCAN_IS_NEWLINE(c) ((c)=='\r' || (c)=='\n') 30 30 #define PJ_SCAN_IS_PROBABLY_SPACE(c) ((c) <= 32) 31 #define PJ_SCAN_CHECK_EOF(s) ( *s)31 #define PJ_SCAN_CHECK_EOF(s) (s != scanner->end) 32 32 33 33 … … 376 376 do { 377 377 /* loop until end_quote is found. */ 378 while ( *s&& *s != '\n' && *s != end_quote[qpair]) {378 while (PJ_SCAN_CHECK_EOF(s) && *s != '\n' && *s != end_quote[qpair]) { 379 379 ++s; 380 380 } -
pjproject/branches/1.0/pjsip-apps/src/pjsua/pjsua_app.c
r2408 r2538 4016 4016 } 4017 4017 4018 /***************************************************************************** 4019 * A simple module to handle otherwise unhandled request. We will register 4020 * this with the lowest priority. 4021 */ 4022 4023 /* Notification on incoming request */ 4024 static pj_bool_t default_mod_on_rx_request(pjsip_rx_data *rdata) 4025 { 4026 pjsip_tx_data *tdata; 4027 pjsip_status_code status_code; 4028 pj_status_t status; 4029 4030 /* Don't respond to ACK! */ 4031 if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, 4032 &pjsip_ack_method) == 0) 4033 return PJ_TRUE; 4034 4035 /* Create basic response. */ 4036 if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, 4037 &pjsip_notify_method) == 0) 4038 { 4039 /* Unsolicited NOTIFY's, send with Bad Request */ 4040 status_code = PJSIP_SC_BAD_REQUEST; 4041 } else { 4042 /* Probably unknown method */ 4043 status_code = PJSIP_SC_METHOD_NOT_ALLOWED; 4044 } 4045 status = pjsip_endpt_create_response(pjsua_get_pjsip_endpt(), 4046 rdata, status_code, 4047 NULL, &tdata); 4048 if (status != PJ_SUCCESS) { 4049 pjsua_perror(THIS_FILE, "Unable to create response", status); 4050 return PJ_TRUE; 4051 } 4052 4053 /* Add Allow if we're responding with 405 */ 4054 if (status_code == PJSIP_SC_METHOD_NOT_ALLOWED) { 4055 const pjsip_hdr *cap_hdr; 4056 cap_hdr = pjsip_endpt_get_capability(pjsua_get_pjsip_endpt(), 4057 PJSIP_H_ALLOW, NULL); 4058 if (cap_hdr) { 4059 pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_clone(tdata->pool, 4060 cap_hdr)); 4061 } 4062 } 4063 4064 /* Add User-Agent header */ 4065 { 4066 pj_str_t user_agent; 4067 char tmp[80]; 4068 const pj_str_t USER_AGENT = { "User-Agent", 10}; 4069 pjsip_hdr *h; 4070 4071 pj_ansi_snprintf(tmp, sizeof(tmp), "PJSUA v%s/%s", 4072 pj_get_version(), PJ_OS_NAME); 4073 pj_strdup2_with_null(tdata->pool, &user_agent, tmp); 4074 4075 h = (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, 4076 &USER_AGENT, 4077 &user_agent); 4078 pjsip_msg_add_hdr(tdata->msg, h); 4079 } 4080 4081 pjsip_endpt_send_response2(pjsua_get_pjsip_endpt(), rdata, tdata, 4082 NULL, NULL); 4083 4084 return PJ_TRUE; 4085 } 4086 4087 4088 /* The module instance. */ 4089 static pjsip_module mod_default_handler = 4090 { 4091 NULL, NULL, /* prev, next. */ 4092 { "mod-default-handler", 19 }, /* Name. */ 4093 -1, /* Id */ 4094 PJSIP_MOD_PRIORITY_APPLICATION+99, /* Priority */ 4095 NULL, /* load() */ 4096 NULL, /* start() */ 4097 NULL, /* stop() */ 4098 NULL, /* unload() */ 4099 &default_mod_on_rx_request, /* on_rx_request() */ 4100 NULL, /* on_rx_response() */ 4101 NULL, /* on_tx_request. */ 4102 NULL, /* on_tx_response() */ 4103 NULL, /* on_tsx_state() */ 4104 4105 }; 4106 4107 4108 4018 4109 4019 4110 /***************************************************************************** … … 4066 4157 return status; 4067 4158 4159 /* Initialize our module to handle otherwise unhandled request */ 4160 status = pjsip_endpt_register_module(pjsua_get_pjsip_endpt(), 4161 &mod_default_handler); 4162 if (status != PJ_SUCCESS) 4163 return status; 4164 4068 4165 #ifdef STEREO_DEMO 4069 4166 stereo_demo(); -
pjproject/branches/1.0/pjsip/include/pjsip/sip_parser.h
r2394 r2538 337 337 pj_cis_t pjsip_TOKEN_SPEC; /**< Token. */ 338 338 pj_cis_t pjsip_TOKEN_SPEC_ESC; /**< Token without '%' character */ 339 pj_cis_t pjsip_VIA_PARAM_SPEC; /**< Via param is token + ":" for 340 IPv6. */ 341 pj_cis_t pjsip_VIA_PARAM_SPEC_ESC; /**< .. as above without '%' */ 339 342 pj_cis_t pjsip_HEX_SPEC; /**< Hexadecimal digits. */ 340 343 pj_cis_t pjsip_PARAM_CHAR_SPEC; /**< For scanning pname (or pvalue -
pjproject/branches/1.0/pjsip/src/pjsip/sip_parser.c
r2394 r2538 54 54 */ 55 55 #define GENERIC_URI_CHARS "#?;:@&=+-_.!~*'()%$,/" "%" 56 57 #define PJSIP_VERSION "SIP/2.0"58 56 59 57 #define UNREACHED(expr) … … 328 326 pj_cis_del_str(&pconst.pjsip_TOKEN_SPEC_ESC, "%"); 329 327 328 status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC, &pconst.pjsip_TOKEN_SPEC); 329 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 330 pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":"); 331 332 status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC); 333 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 334 pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":"); 335 330 336 status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC); 331 337 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); … … 773 779 const char *line; 774 780 int content_length = -1; 781 pj_str_t cur_msg; 782 const pj_str_t end_hdr = { "\n\r\n", 3}; 775 783 776 784 *msg_size = size; … … 782 790 783 791 784 /* Find the end of header area by finding an empty line. */ 785 pos = pj_ansi_strstr(buf, "\n\r\n"); 792 /* Find the end of header area by finding an empty line. 793 * Don't use plain strstr() since we want to be able to handle 794 * NULL character in the message 795 */ 796 cur_msg.ptr = (char*)buf; cur_msg.slen = size; 797 pos = pj_strstr(&cur_msg, &end_hdr); 786 798 if (pos == NULL) { 787 799 return PJSIP_EPARTIALMSG; … … 792 804 793 805 /* Find "Content-Length" header the hard way. */ 794 line = pj_ ansi_strchr(buf, '\n');806 line = pj_strchr(&cur_msg, '\n'); 795 807 while (line && line < hdr_end) { 796 808 ++line; … … 843 855 844 856 /* Go to next line. */ 845 line = pj_ansi_strchr(line, '\n'); 857 cur_msg.slen -= (line - cur_msg.ptr); 858 cur_msg.ptr = (char*)line; 859 line = pj_strchr(&cur_msg, '\n'); 846 860 } 847 861 … … 894 908 } 895 909 910 /* SIP version */ 911 static void parse_sip_version(pj_scanner *scanner) 912 { 913 pj_str_t SIP = { "SIP", 3 }; 914 pj_str_t V2 = { "2.0", 3 }; 915 pj_str_t sip, version; 916 917 pj_scan_get( scanner, &pconst.pjsip_ALPHA_SPEC, &sip); 918 if (pj_scan_get_char(scanner) != '/') 919 on_syntax_error(scanner); 920 pj_scan_get_n( scanner, 3, &version); 921 if (pj_stricmp(&sip, &SIP) || pj_stricmp(&version, &V2)) 922 on_syntax_error(scanner); 923 } 924 925 static pj_bool_t is_next_sip_version(pj_scanner *scanner) 926 { 927 pj_str_t SIP = { "SIP", 3 }; 928 pj_str_t sip; 929 int c; 930 931 c = pj_scan_peek(scanner, &pconst.pjsip_ALPHA_SPEC, &sip); 932 /* return TRUE if it is "SIP" followed by "/" or space. 933 * we include space since the "/" may be separated by space, 934 * although this would mean it would return TRUE if it is a 935 * request and the method is "SIP"! 936 */ 937 return c && (c=='/' || c==' ' || c=='\t') && pj_stricmp(&sip, &SIP)==0; 938 } 939 896 940 /* Internal function to parse SIP message */ 897 941 static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, … … 927 971 928 972 /* Parse request or status line */ 929 if ( pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) {973 if (is_next_sip_version(scanner)) { 930 974 msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG); 931 975 int_parse_status_line( scanner, &msg->line.status ); … … 1126 1170 1127 1171 1128 /* Parse parameter (";" pname ["=" pvalue]) in header. */1172 /* Parse parameter (";" pname ["=" pvalue]) in SIP header. */ 1129 1173 static void int_parse_param( pj_scanner *scanner, pj_pool_t *pool, 1130 1174 pj_str_t *pname, pj_str_t *pvalue, … … 1514 1558 1515 1559 req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE); 1516 if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0) 1517 PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); 1518 pj_scan_advance_n (scanner, 7, 1); 1560 parse_sip_version(scanner); 1519 1561 pj_scan_get_newline( scanner ); 1520 1562 } … … 1526 1568 pj_str_t token; 1527 1569 1528 if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0) 1529 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 1530 pj_scan_advance_n( scanner, 7, 1); 1531 1570 parse_sip_version(scanner); 1532 1571 pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token); 1533 1572 status_line->code = pj_strtoul(&token); … … 1619 1658 /* Parse generic string header. */ 1620 1659 static void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr, 1621 pj_scanner *scanner ) 1622 { 1623 if (pj_cis_match(&pconst.pjsip_NOT_NEWLINE, *scanner->curptr)) 1660 pjsip_parse_ctx *ctx) 1661 { 1662 pj_scanner *scanner = ctx->scanner; 1663 1664 hdr->hvalue.slen = 0; 1665 1666 /* header may be mangled hence the loop */ 1667 while (pj_cis_match(&pconst.pjsip_NOT_NEWLINE, *scanner->curptr)) { 1668 pj_str_t next, tmp; 1669 1624 1670 pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &hdr->hvalue); 1625 else 1626 hdr->hvalue.slen = 0; 1671 if (pj_scan_is_eof(scanner) || IS_NEWLINE(*scanner->curptr)) 1672 break; 1673 /* mangled, get next fraction */ 1674 pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &next); 1675 /* concatenate */ 1676 tmp.ptr = (char*)pj_pool_alloc(ctx->pool, 1677 hdr->hvalue.slen + next.slen + 2); 1678 tmp.slen = 0; 1679 pj_strcpy(&tmp, &hdr->hvalue); 1680 pj_strcat2(&tmp, " "); 1681 pj_strcat(&tmp, &next); 1682 tmp.ptr[tmp.slen] = '\0'; 1683 1684 hdr->hvalue = tmp; 1685 } 1627 1686 1628 1687 parse_hdr_end(scanner); … … 1935 1994 1936 1995 //Parse with PARAM_CHAR instead, to allow IPv6 1996 //No, back to using int_parse_param() for the "`" character! 1937 1997 //int_parse_param( scanner, pool, &pname, &pvalue, 0); 1938 /* Get ';' character */ 1998 //parse_param_imp(scanner, pool, &pname, &pvalue, 1999 // &pconst.pjsip_TOKEN_SPEC, 2000 // &pconst.pjsip_TOKEN_SPEC_ESC, 0); 2001 //int_parse_param(scanner, pool, &pname, &pvalue, 0); 2002 // This should be the correct one: 2003 // added special spec for Via parameter, basically token plus 2004 // ":" to allow IPv6 address in the received param. 1939 2005 pj_scan_get_char(scanner); 1940 1941 parse_param_imp(scanner, pool, &pname, &pvalue,1942 &pconst.pjsip_ PARAM_CHAR_SPEC,1943 &pconst.pjsip_PARAM_CHAR_SPEC_ESC,0);2006 parse_param_imp(scanner, pool, &pname, &pvalue, 2007 &pconst.pjsip_VIA_PARAM_SPEC, 2008 &pconst.pjsip_VIA_PARAM_SPEC_ESC, 2009 0); 1944 2010 1945 2011 if (!parser_stricmp(pname, pconst.pjsip_BRANCH_STR) && pvalue.slen) { … … 2076 2142 pj_list_insert_before(first, hdr); 2077 2143 2078 if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0) 2079 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 2080 2081 pj_scan_advance_n( scanner, 8, 1); 2144 parse_sip_version(scanner); 2145 if (pj_scan_get_char(scanner) != '/') 2146 on_syntax_error(scanner); 2082 2147 2083 2148 pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->transport); … … 2120 2185 2121 2186 hdr = pjsip_generic_string_hdr_create(ctx->pool, NULL, NULL); 2122 parse_generic_string_hdr(hdr, ctx ->scanner);2187 parse_generic_string_hdr(hdr, ctx); 2123 2188 return (pjsip_hdr*)hdr; 2124 2189 -
pjproject/branches/1.0/pjsip/src/test-pjsip/msg_test.c
r2394 r2538 74 74 "\r\n", 75 75 &create_msg0, 76 0, 76 77 PJ_SUCCESS 77 78 }, … … 101 102 "a=rtpmap:0 PCMU/8000\r\n", 102 103 &create_msg1, 104 0, 105 PJ_SUCCESS 106 }, 107 { 108 /* Torture message from RFC 4475 109 * 3.1.1.1 A short tortuous INVITE 110 */ 111 "INVITE sip:vivekg@chair-dnrc.example.com;unknownparam SIP/2.0\n" 112 "TO :\n" 113 " sip:vivekg@chair-dnrc.example.com ; tag = 1918181833n\n" 114 "from : \"J Rosenberg \\\\\\\"\" <sip:jdrosen@example.com>\n" 115 " ;\n" 116 " tag = 98asjd8\n" 117 "MaX-fOrWaRdS: 0068\n" 118 "Call-ID: wsinv.ndaksdj@192.0.2.1\n" 119 "Content-Length : 150\n" 120 "cseq: 0009\n" 121 " INVITE\n" 122 "Via : SIP / 2.0\n" 123 " /UDP\n" 124 " 192.0.2.2;rport;branch=390skdjuw\n" 125 "s :\n" 126 "NewFangledHeader: newfangled value\n" 127 " continued newfangled value\n" 128 "UnknownHeaderWithUnusualValue: ;;,,;;,;\n" 129 "Content-Type: application/sdp\n" 130 "Route:\n" 131 " <sip:services.example.com;lr;unknownwith=value;unknown-no-value>\n" 132 "v: SIP / 2.0 / TCP spindle.example.com ;\n" 133 " branch = z9hG4bK9ikj8 ,\n" 134 " SIP / 2.0 / UDP 192.168.255.111 ; branch=\n" 135 " z9hG4bK30239\n" 136 "m:\"Quoted string \\\"\\\"\" <sip:jdrosen@example.com> ; newparam =\n" 137 " newvalue ;\n" 138 " secondparam ; q = 0.33\r\n" 139 "\r\n" 140 "v=0\r\n" 141 "o=mhandley 29739 7272939 IN IP4 192.0.2.3\r\n" 142 "s=-\r\n" 143 "c=IN IP4 192.0.2.4\r\n" 144 "t=0 0\r\n" 145 "m=audio 49217 RTP/AVP 0 12\r\n" 146 "m=video 3227 RTP/AVP 31\r\n" 147 "a=rtpmap:31 LPC\r\n", 148 NULL, 149 0, 150 PJ_SUCCESS 151 }, 152 { 153 /* Torture message from RFC 4475 154 * 3.1.1.2 Wide Range of Valid Characters 155 */ 156 "!interesting-Method0123456789_*+`.%indeed'~ sip:1_unusual.URI~(to-be!sure)&isn't+it$/crazy?,/;;*:&it+has=1,weird!*pas$wo~d_too.(doesn't-it)@example.com SIP/2.0\n" 157 "Via: SIP/2.0/UDP host1.example.com;rport;branch=z9hG4bK-.!%66*_+`'~\n" 158 "To: \"BEL:\\\x07 NUL:\\\x00 DEL:\\\x7F\" <sip:1_unusual.URI~(to-be!sure)&isn't+it$/crazy?,/;;*@example.com>\n" 159 "From: token1~` token2'+_ token3*%!.- <sip:mundane@example.com> ;fromParam''~+*_!.-%=\"\xD1\x80\xD0\xB0\xD0\xB1\xD0\xBE\xD1\x82\xD0\xB0\xD1\x8E\xD1\x89\xD0\xB8\xD0\xB9\";tag=_token~1'+`*%!-.\n" 160 "Call-ID: intmeth.word%ZK-!.*_+'@word`~)(><:\\/\"][?}{\n" 161 "CSeq: 139122385 !interesting-Method0123456789_*+`.%indeed'~\n" 162 "Max-Forwards: 255\n" 163 "extensionHeader-!.%*+_`'~: \xEF\xBB\xBF\xE5\xA4\xA7\xE5\x81\x9C\xE9\x9B\xBB\n" 164 "Content-Length: 0\r\n\r\n", 165 NULL, 166 641, 167 PJ_SUCCESS 168 }, 169 { 170 /* Torture message from RFC 4475 171 * 3.1.1.3 Valid Use of the % Escaping Mechanism 172 */ 173 "INVITE sip:sips%3Auser%40example.com@example.net SIP/2.0\n" 174 "To: sip:%75se%72@example.com\n" 175 "From: <sip:I%20have%20spaces@example.net>;tag=1234\n" 176 "Max-Forwards: 87\n" 177 "i: esc01.239409asdfakjkn23onasd0-3234\n" 178 "CSeq: 234234 INVITE\n" 179 "Via: SIP/2.0/UDP host5.example.net;rport;branch=z9hG4bKkdjuw\n" 180 "C: application/sdp\n" 181 "Contact:\n" 182 " <sip:cal%6Cer@192.168.0.2:5060;%6C%72;n%61me=v%61lue%25%34%31>\n" 183 "Content-Length: 150\r\n" 184 "\r\n" 185 "v=0\r\n" 186 "o=mhandley 29739 7272939 IN IP4 192.0.2.1\r\n" 187 "s=-\r\n" 188 "c=IN IP4 192.0.2.1\r\n" 189 "t=0 0\r\n" 190 "m=audio 49217 RTP/AVP 0 12\r\n" 191 "m=video 3227 RTP/AVP 31\r\n" 192 "a=rtpmap:31 LPC\r\n", 193 NULL, 194 0, 195 PJ_SUCCESS 196 }, 197 { 198 /* Torture message from RFC 4475 199 * 3.1.1.4 Escaped Nulls in URIs 200 */ 201 "REGISTER sip:example.com SIP/2.0\r\n" 202 "To: sip:null-%00-null@example.com\r\n" 203 "From: sip:null-%00-null@example.com;tag=839923423\r\n" 204 "Max-Forwards: 70\r\n" 205 "Call-ID: escnull.39203ndfvkjdasfkq3w4otrq0adsfdfnavd\r\n" 206 "CSeq: 14398234 REGISTER\r\n" 207 "Via: SIP/2.0/UDP host5.example.com;rport;branch=z9hG4bKkdjuw\r\n" 208 "Contact: <sip:%00@host5.example.com>\r\n" 209 "Contact: <sip:%00%00@host5.example.com>\r\n" 210 "L:0\r\n" 211 "\r\n", 212 NULL, 213 0, 214 PJ_SUCCESS 215 }, 216 { 217 /* Torture message from RFC 4475 218 * 3.1.1.5 Use of % When It Is Not an Escape 219 */ 220 "RE%47IST%45R sip:registrar.example.com SIP/2.0\r\n" 221 "To: \"%Z%45\" <sip:resource@example.com>\r\n" 222 "From: \"%Z%45\" <sip:resource@example.com>;tag=f232jadfj23\r\n" 223 "Call-ID: esc02.asdfnqwo34rq23i34jrjasdcnl23nrlknsdf\r\n" 224 "Via: SIP/2.0/TCP host.example.com;rport;branch=z9hG4bK209%fzsnel234\r\n" 225 "CSeq: 29344 RE%47IST%45R\r\n" 226 "Max-Forwards: 70\r\n" 227 "Contact: <sip:alias1@host1.example.com>\r\n" 228 "C%6Fntact: <sip:alias2@host2.example.com>\r\n" 229 "Contact: <sip:alias3@host3.example.com>\r\n" 230 "l: 0\r\n" 231 "\r\n", 232 NULL, 233 0, 103 234 PJ_SUCCESS 104 235 } … … 127 258 enum { BUFLEN = 512 }; 128 259 129 entry->len = pj_ansi_strlen(entry->msg); 260 if (entry->len==0) 261 entry->len = pj_ansi_strlen(entry->msg); 130 262 131 263 if (var.flag & FLAG_PARSE_ONLY) … … 181 313 pj_add_timestamp(&var.parse_time, &t2); 182 314 183 if ( var.flag & FLAG_PARSE_ONLY)315 if ((var.flag & FLAG_PARSE_ONLY) || entry->creator==NULL) 184 316 return PJ_SUCCESS; 185 317
Note: See TracChangeset
for help on using the changeset viewer.