- Timestamp:
- Apr 1, 2007 10:58:47 PM (18 years ago)
- Location:
- pjproject/branches/pjproject-0.5-stable
- Files:
-
- 3 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/pjproject-0.5-stable/pjsip-apps/build/Samples-vc.mak
r922 r1121 50 50 $(BINDIR)\sndinfo.exe \ 51 51 $(BINDIR)\sndtest.exe \ 52 $(BINDIR)\stateful_proxy.exe \ 53 $(BINDIR)\stateless_proxy.exe \ 52 54 $(BINDIR)\streamutil.exe \ 53 55 $(BINDIR)\tonegen.exe -
pjproject/branches/pjproject-0.5-stable/pjsip-apps/build/Samples.mak
r876 r1121 53 53 sndinfo \ 54 54 sndtest \ 55 stateful_proxy \ 56 stateless_proxy \ 55 57 streamutil \ 56 58 tonegen -
pjproject/branches/pjproject-0.5-stable/pjsip-apps/build/samples.dsp
r922 r1121 155 155 # Begin Source File 156 156 157 SOURCE=..\src\samples\stateful_proxy.c 158 # End Source File 159 # Begin Source File 160 161 SOURCE=..\src\samples\stateless_proxy.c 162 # End Source File 163 # Begin Source File 164 157 165 SOURCE=..\src\samples\streamutil.c 158 166 # End Source File … … 165 173 166 174 # PROP Default_Filter "h;hpp;hxx;hm;inl" 175 # Begin Source File 176 177 SOURCE=..\src\samples\proxy.h 178 # End Source File 167 179 # Begin Source File 168 180 -
pjproject/branches/pjproject-0.5-stable/pjsip-apps/build/samples.vcproj
r922 r1121 5 5 Name="samples" 6 6 ProjectGUID="{E378A1FC-0C9C-4462-860F-7E60BC1BF84E}" 7 RootNamespace="samples" 7 8 Keyword="MakeFileProj" 8 9 > … … 138 139 </File> 139 140 <File 141 RelativePath="..\src\samples\stateful_proxy.c" 142 > 143 </File> 144 <File 145 RelativePath="..\src\samples\stateless_proxy.c" 146 > 147 </File> 148 <File 140 149 RelativePath="..\src\samples\streamutil.c" 141 150 > … … 150 159 Filter="h;hpp;hxx;hm;inl" 151 160 > 161 <File 162 RelativePath="..\src\samples\proxy.h" 163 > 164 </File> 152 165 <File 153 166 RelativePath="..\src\samples\util.h" -
pjproject/branches/pjproject-0.5-stable/pjsip/include/pjsip/sip_msg.h
r974 r1121 711 711 PJ_DECL(pjsip_msg*) pjsip_msg_create( pj_pool_t *pool, pjsip_msg_type_e type); 712 712 713 714 /** 715 * Perform a deep clone of a SIP message. 716 * 717 * @param pool The pool for creating the new message. 718 * @param msg The message to be duplicated. 719 * 720 * @return New message, which is duplicated from the original 721 * message. 722 */ 723 PJ_DECL(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *msg); 724 725 713 726 /** 714 727 * Find a header in the message by the header type. -
pjproject/branches/pjproject-0.5-stable/pjsip/include/pjsip/sip_util.h
r1077 r1121 473 473 474 474 /** 475 * @} 476 */ 477 478 /** 479 * @defgroup PJSIP_PROXY_CORE Core Proxy Layer 480 * @ingroup PJSIP 481 * @brief Core proxy operations 482 * @{ 483 */ 484 485 /** 475 486 * Create new request message to be forwarded upstream to new destination URI 476 487 * in uri. The new request is a full/deep clone of the request received in … … 479 490 * the Via header. If it is NULL, then a unique branch parameter will be used. 480 491 * 492 * Note: this function DOES NOT perform Route information preprocessing as 493 * described in RFC 3261 Section 16.4. Application must take care of 494 * removing/updating the Route headers according of the rules as 495 * described in that section. 496 * 481 497 * @param endpt The endpoint instance. 482 498 * @param rdata The incoming request message. 483 499 * @param uri The URI where the request will be forwarded to. 484 * @param branch Optional branch parameter. 500 * @param branch Optional branch parameter. Application may specify its 501 * own branch, for example if it wishes to perform loop 502 * detection. If the branch parameter is not specified, 503 * this function will generate its own by calling 504 * #pjsip_calculate_branch_id() function. 485 505 * @param options Optional option flags when duplicating the message. 486 506 * @param tdata The result. … … 488 508 * @return PJ_SUCCESS on success. 489 509 */ 490 PJ_DECL(pj_status_t) pjsip_endpt_create_request_fwd( pjsip_endpoint *endpt, 491 pjsip_rx_data *rdata, 492 const pjsip_uri *uri, 493 const pj_str_t *branch, 494 unsigned options, 495 pjsip_tx_data **tdata); 510 PJ_DECL(pj_status_t) pjsip_endpt_create_request_fwd(pjsip_endpoint *endpt, 511 pjsip_rx_data *rdata, 512 const pjsip_uri *uri, 513 const pj_str_t *branch, 514 unsigned options, 515 pjsip_tx_data **tdata); 516 517 496 518 497 519 /** … … 516 538 517 539 540 518 541 /** 519 542 * Create a globally unique branch parameter based on the information in 520 * the incoming request message. This function guarantees that subsequent 521 * retransmissions of the same request will generate the same branch id. 522 * This function can also be used in the loop detection process. 523 * If the same request arrives back in the proxy with the same URL, it will 524 * calculate into the same branch id. 543 * the incoming request message, for the purpose of creating a new request 544 * for forwarding. This is the default implementation used by 545 * #pjsip_endpt_create_request_fwd() function if the branch parameter is 546 * not specified. 547 * 548 * The default implementation here will just create an MD5 hash of the 549 * top-most Via. 550 * 525 551 * Note that the returned string was allocated from rdata's pool. 526 552 * -
pjproject/branches/pjproject-0.5-stable/pjsip/src/pjsip/sip_msg.c
r974 r1121 248 248 } 249 249 250 PJ_DEF(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *src) 251 { 252 pjsip_msg *dst; 253 const pjsip_hdr *sh; 254 255 dst = pjsip_msg_create(pool, src->type); 256 257 /* Clone request/status line */ 258 if (src->type == PJSIP_REQUEST_MSG) { 259 pjsip_method_copy(pool, &dst->line.req.method, &src->line.req.method); 260 dst->line.req.uri = pjsip_uri_clone(pool, src->line.req.uri); 261 } else { 262 dst->line.status.code = src->line.status.code; 263 pj_strdup(pool, &dst->line.status.reason, &src->line.status.reason); 264 } 265 266 /* Clone headers */ 267 sh = src->hdr.next; 268 while (sh != &src->hdr) { 269 pjsip_hdr *dh = pjsip_hdr_clone(pool, sh); 270 pjsip_msg_add_hdr(dst, dh); 271 sh = sh->next; 272 } 273 274 /* Clone message body */ 275 if (src->body) { 276 dst->body = pjsip_msg_body_clone(pool, src->body); 277 } 278 279 return dst; 280 } 281 250 282 PJ_DEF(void*) pjsip_msg_find_hdr( const pjsip_msg *msg, 251 283 pjsip_hdr_e hdr_type, const void *start) -
pjproject/branches/pjproject-0.5-stable/pjsip/src/pjsip/sip_util.c
r1078 r1121 1037 1037 /* Check arguments. */ 1038 1038 PJ_ASSERT_RETURN(pool && rdata && res_addr, PJ_EINVAL); 1039 1040 /* rdata must be a request message! */ 1041 PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG, 1042 PJ_EINVAL); 1039 1043 1040 1044 /* All requests must have "received" parameter. -
pjproject/branches/pjproject-0.5-stable/pjsip/src/pjsip/sip_util_proxy.c
r974 r1121 18 18 */ 19 19 #include <pjsip/sip_util.h> 20 #include <pjsip/sip_endpoint.h> 20 21 #include <pjsip/sip_errno.h> 22 #include <pjsip/sip_msg.h> 21 23 #include <pj/assert.h> 22 23 PJ_DEF(pj_status_t) pjsip_endpt_create_request_fwd( pjsip_endpoint *endpt, 24 pjsip_rx_data *rdata, 25 const pjsip_uri *uri, 26 const pj_str_t *branch, 27 unsigned options, 28 pjsip_tx_data **tdata) 29 { 30 PJ_UNUSED_ARG(endpt); 31 PJ_UNUSED_ARG(rdata); 32 PJ_UNUSED_ARG(uri); 33 PJ_UNUSED_ARG(branch); 24 #include <pj/ctype.h> 25 #include <pj/except.h> 26 #include <pj/pool.h> 27 #include <pj/string.h> 28 #include <pjlib-util/md5.h> 29 30 31 /** 32 * Clone the incoming SIP request or response message. A forwarding proxy 33 * typically would need to clone the incoming SIP message before processing 34 * the message. 35 * 36 * Once a transmit data is created, the reference counter is initialized to 1. 37 * 38 * @param endpt The endpoint instance. 39 * @param rdata The incoming SIP message. 40 * @param p_tdata Pointer to receive the transmit data containing 41 * the duplicated message. 42 * 43 * @return PJ_SUCCESS on success. 44 */ 45 PJ_DEF(pj_status_t) pjsip_endpt_clone_msg( pjsip_endpoint *endpt, 46 const pjsip_rx_data *rdata, 47 pjsip_tx_data **p_tdata) 48 { 49 pjsip_tx_data *tdata; 50 pj_status_t status; 51 52 status = pjsip_endpt_create_tdata(endpt, &tdata); 53 if (status != PJ_SUCCESS) 54 return status; 55 56 tdata->msg = pjsip_msg_clone(tdata->pool, rdata->msg_info.msg); 57 58 pjsip_tx_data_add_ref(tdata); 59 60 *p_tdata = tdata; 61 62 return PJ_SUCCESS; 63 } 64 65 66 /* 67 * Create new request message to be forwarded upstream to new destination URI 68 * in uri. 69 */ 70 PJ_DEF(pj_status_t) pjsip_endpt_create_request_fwd(pjsip_endpoint *endpt, 71 pjsip_rx_data *rdata, 72 const pjsip_uri *uri, 73 const pj_str_t *branch, 74 unsigned options, 75 pjsip_tx_data **p_tdata) 76 { 77 pjsip_tx_data *tdata; 78 pj_status_t status; 79 PJ_USE_EXCEPTION; 80 81 82 PJ_ASSERT_RETURN(endpt && rdata && p_tdata, PJ_EINVAL); 83 PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG, 84 PJSIP_ENOTREQUESTMSG); 85 34 86 PJ_UNUSED_ARG(options); 35 PJ_UNUSED_ARG(tdata); 36 37 pj_assert(!"Not implemented yet"); 38 return PJ_EBUG; 87 88 89 /* Request forwarding rule in RFC 3261 section 16.6: 90 * 91 * For each target, the proxy forwards the request following these 92 * steps: 93 * 94 * 1. Make a copy of the received request 95 * 2. Update the Request-URI 96 * 3. Update the Max-Forwards header field 97 * 4. Optionally add a Record-route header field value 98 * 5. Optionally add additional header fields 99 * 6. Postprocess routing information 100 * 7. Determine the next-hop address, port, and transport 101 * 8. Add a Via header field value 102 * 9. Add a Content-Length header field if necessary 103 * 10. Forward the new request 104 * 105 * Of these steps, we only do step 1-3, since the later will be 106 * done by application. 107 */ 108 109 status = pjsip_endpt_create_tdata(endpt, &tdata); 110 if (status != PJ_SUCCESS) 111 return status; 112 113 /* Always increment ref counter to 1 */ 114 pjsip_tx_data_add_ref(tdata); 115 116 /* Duplicate the request */ 117 PJ_TRY { 118 pjsip_msg *dst; 119 const pjsip_msg *src = rdata->msg_info.msg; 120 const pjsip_hdr *hsrc; 121 122 /* Create the request */ 123 tdata->msg = dst = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG); 124 125 /* Duplicate request method */ 126 pjsip_method_copy(tdata->pool, &tdata->msg->line.req.method, 127 &src->line.req.method); 128 129 /* Set request URI */ 130 if (uri) { 131 dst->line.req.uri = pjsip_uri_clone(tdata->pool, uri); 132 } else { 133 dst->line.req.uri = pjsip_uri_clone(tdata->pool, src->line.req.uri); 134 } 135 136 /* Clone ALL headers */ 137 hsrc = src->hdr.next; 138 while (hsrc != &src->hdr) { 139 140 pjsip_hdr *hdst; 141 142 /* If this is the top-most Via header, insert our own before 143 * cloning the header. 144 */ 145 if (hsrc == (pjsip_hdr*)rdata->msg_info.via) { 146 pjsip_via_hdr *hvia; 147 hvia = pjsip_via_hdr_create(tdata->pool); 148 if (branch) 149 pj_strdup(tdata->pool, &hvia->branch_param, branch); 150 else { 151 pj_str_t new_branch = pjsip_calculate_branch_id(rdata); 152 pj_strdup(tdata->pool, &hvia->branch_param, &new_branch); 153 } 154 pjsip_msg_add_hdr(dst, (pjsip_hdr*)hvia); 155 156 } 157 /* Skip Content-Type and Content-Length as these would be 158 * generated when the the message is printed. 159 */ 160 else if (hsrc->type == PJSIP_H_CONTENT_LENGTH || 161 hsrc->type == PJSIP_H_CONTENT_TYPE) { 162 163 hsrc = hsrc->next; 164 continue; 165 166 } 167 #if 0 168 /* If this is the top-most Route header and it indicates loose 169 * route, remove the header. 170 */ 171 else if (hsrc == (pjsip_hdr*)rdata->msg_info.route) { 172 173 const pjsip_route_hdr *hroute = (const pjsip_route_hdr*) hsrc; 174 const pjsip_sip_uri *sip_uri; 175 176 if (!PJSIP_URI_SCHEME_IS_SIP(hroute->name_addr.uri) && 177 !PJSIP_URI_SCHEME_IS_SIPS(hroute->name_addr.uri)) 178 { 179 /* This is a bad request! */ 180 status = PJSIP_EINVALIDHDR; 181 goto on_error; 182 } 183 184 sip_uri = (pjsip_sip_uri*) hroute->name_addr.uri; 185 186 if (sip_uri->lr_param) { 187 /* Yes lr param is present, skip this Route header */ 188 hsrc = hsrc->next; 189 continue; 190 } 191 } 192 #endif 193 194 /* Clone the header */ 195 hdst = pjsip_hdr_clone(tdata->pool, hsrc); 196 197 /* If this is Max-Forward header, decrement the value */ 198 if (hdst->type == PJSIP_H_MAX_FORWARDS) { 199 pjsip_max_fwd_hdr *hmaxfwd = (pjsip_max_fwd_hdr*)hdst; 200 --hmaxfwd->ivalue; 201 } 202 203 /* Append header to new request */ 204 pjsip_msg_add_hdr(dst, hdst); 205 206 207 hsrc = hsrc->next; 208 } 209 210 /* 16.6.3: 211 * If the copy does not contain a Max-Forwards header field, the 212 * proxy MUST add one with a field value, which SHOULD be 70. 213 */ 214 if (rdata->msg_info.max_fwd == NULL) { 215 pjsip_max_fwd_hdr *hmaxfwd = 216 pjsip_max_fwd_hdr_create(tdata->pool, 70); 217 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hmaxfwd); 218 } 219 220 /* Clone request body */ 221 if (src->body) { 222 dst->body = pjsip_msg_body_clone(tdata->pool, src->body); 223 } 224 225 } 226 PJ_CATCH_ANY { 227 status = PJ_ENOMEM; 228 goto on_error; 229 } 230 PJ_END 231 232 233 /* Done */ 234 *p_tdata = tdata; 235 return PJ_SUCCESS; 236 237 on_error: 238 pjsip_tx_data_dec_ref(tdata); 239 return status; 39 240 } 40 241 … … 43 244 pjsip_rx_data *rdata, 44 245 unsigned options, 45 pjsip_tx_data **tdata) 46 { 47 PJ_UNUSED_ARG(endpt); 48 PJ_UNUSED_ARG(rdata); 246 pjsip_tx_data **p_tdata) 247 { 248 pjsip_tx_data *tdata; 249 pj_status_t status; 250 PJ_USE_EXCEPTION; 251 49 252 PJ_UNUSED_ARG(options); 50 PJ_UNUSED_ARG(tdata); 51 52 pj_assert(!"Not implemented yet"); 53 return PJ_EBUG; 253 254 status = pjsip_endpt_create_tdata(endpt, &tdata); 255 if (status != PJ_SUCCESS) 256 return status; 257 258 pjsip_tx_data_add_ref(tdata); 259 260 PJ_TRY { 261 pjsip_msg *dst; 262 const pjsip_msg *src = rdata->msg_info.msg; 263 const pjsip_hdr *hsrc; 264 265 /* Create the request */ 266 tdata->msg = dst = pjsip_msg_create(tdata->pool, PJSIP_RESPONSE_MSG); 267 268 /* Clone the status line */ 269 dst->line.status.code = src->line.status.code; 270 pj_strdup(tdata->pool, &dst->line.status.reason, 271 &src->line.status.reason); 272 273 /* Duplicate all headers */ 274 hsrc = src->hdr.next; 275 while (hsrc != &src->hdr) { 276 277 /* Skip Content-Type and Content-Length as these would be 278 * generated when the the message is printed. 279 */ 280 if (hsrc->type == PJSIP_H_CONTENT_LENGTH || 281 hsrc->type == PJSIP_H_CONTENT_TYPE) { 282 283 hsrc = hsrc->next; 284 continue; 285 286 } 287 /* Remove the first Via header */ 288 else if (hsrc == (pjsip_hdr*) rdata->msg_info.via) { 289 290 hsrc = hsrc->next; 291 continue; 292 } 293 294 pjsip_msg_add_hdr(dst, pjsip_hdr_clone(tdata->pool, hsrc)); 295 296 hsrc = hsrc->next; 297 } 298 299 /* Clone message body */ 300 if (src->body) 301 dst->body = pjsip_msg_body_clone(tdata->pool, src->body); 302 303 304 } 305 PJ_CATCH_ANY { 306 status = PJ_ENOMEM; 307 goto on_error; 308 } 309 PJ_END; 310 311 *p_tdata = tdata; 312 return PJ_SUCCESS; 313 314 on_error: 315 pjsip_tx_data_dec_ref(tdata); 316 return status; 317 } 318 319 320 static void digest2str(const unsigned char digest[], char *output) 321 { 322 int i; 323 for (i = 0; i<16; ++i) { 324 pj_val_to_hex_digit(digest[i], output); 325 output += 2; 326 } 54 327 } 55 328 … … 57 330 PJ_DEF(pj_str_t) pjsip_calculate_branch_id( pjsip_rx_data *rdata ) 58 331 { 59 pj_str_t empty_str = { NULL, 0 }; 60 61 PJ_UNUSED_ARG(rdata); 62 pj_assert(!"Not implemented yet"); 63 return empty_str; 64 } 65 66 332 pj_md5_context ctx; 333 pj_uint8_t digest[16]; 334 pj_str_t branch; 335 336 /* Create branch ID for new request by calculating MD5 hash 337 * of the branch parameter in top-most Via header. 338 */ 339 pj_md5_init(&ctx); 340 pj_md5_update(&ctx, (pj_uint8_t*)rdata->msg_info.via->branch_param.ptr, 341 rdata->msg_info.via->branch_param.slen); 342 pj_md5_final(&ctx, digest); 343 344 branch.ptr = pj_pool_alloc(rdata->tp_info.pool, 345 32 + PJSIP_RFC3261_BRANCH_LEN); 346 pj_memcpy(branch.ptr, PJSIP_RFC3261_BRANCH_ID, PJSIP_RFC3261_BRANCH_LEN); 347 348 digest2str(digest, branch.ptr+PJSIP_RFC3261_BRANCH_LEN); 349 350 branch.slen = 32 + PJSIP_RFC3261_BRANCH_LEN; 351 352 return branch; 353 } 354 355
Note: See TracChangeset
for help on using the changeset viewer.