- Timestamp:
- Nov 18, 2005 10:43:42 PM (19 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip/sip_config.h
r51 r54 63 63 #define PJSIP_POOL_LEN_DIALOG 1200 64 64 #define PJSIP_POOL_INC_DIALOG 512 65 66 /* Transport manager hash table size (must be 2^n-1). */ 67 #define PJSIP_TPMGR_HTABLE_SIZE 31 68 69 /* Transport idle timeout before it's destroyed. */ 70 #define PJSIP_TRANSPORT_IDLE_TIME 30 71 72 /* Max entries to process in timer heap per poll. */ 73 #define PJSIP_MAX_TIMED_OUT_ENTRIES 10 65 74 66 75 /* Module related constants. */ -
pjproject/trunk/pjsip/include/pjsip/sip_endpoint.h
r51 r54 260 260 * @see pjsip_transport_get 261 261 */ 262 PJ_DECL(void) pjsip_endpt_get_transport( pjsip_endpoint *endpt, 263 pj_pool_t *pool, 264 pjsip_transport_type_e type, 265 const pj_sockaddr_in *remote, 266 void *token, 267 pjsip_transport_completion_callback *cb); 268 269 /** 270 * Create listener a new transport listener. A listener is transport object 271 * that is capable of receiving SIP messages. For UDP listener, normally 272 * application should use #pjsip_endpt_create_udp_listener instead if the 273 * application has already created the socket. 274 * This function, like all other endpoint functions, is thread safe. 275 * 276 * @param endpt The endpoint instance. 277 * @param type Transport type (eg. UDP, TCP, etc.) 278 * @param addr The bound address of the transport. 279 * @param addr_name The address to be advertised in SIP messages. For example, 280 * the bound address can be 0.0.0.0, but the advertised address 281 * normally will be the IP address of the host. 282 * 283 * @return Zero if listener is created successfully. 284 */ 285 PJ_DECL(pj_status_t) pjsip_endpt_create_listener( pjsip_endpoint *endpt, 262 PJ_DECL(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt, 286 263 pjsip_transport_type_e type, 287 pj_sockaddr_in *addr, 288 const pj_sockaddr_in *addr_name); 289 290 /** 291 * Create UDP listener. For UDP, normally the application would create the 292 * socket by itself (for STUN purpose), then it can register the socket as 293 * listener by calling this function. 294 * This function, like all other endpoint functions, is thread safe. 295 * 296 * @param endpt The endpoint instance. 297 * @param sock The socket handle. 298 * @param addr_name The address to be advertised in SIP message. If the socket 299 * has been resolved with STUN, then application may specify 300 * the mapped address in this parameter. 301 * 302 * @return Zero if listener is created successfully. 303 */ 304 PJ_DECL(pj_status_t) pjsip_endpt_create_udp_listener( pjsip_endpoint *endpt, 305 pj_sock_t sock, 306 const pj_sockaddr_in *addr_name); 264 const pj_sockaddr_in *remote, 265 pjsip_transport **p_transport); 307 266 308 267 /** -
pjproject/trunk/pjsip/include/pjsip/sip_errno.h
r51 r54 55 55 /** 56 56 * @hideinitializer 57 * Invalid message (syntax error) 58 */ 59 #define PJSIP_EINVALIDMSG (PJSIP_ERRNO_START_PJSIP + 0) 60 /** 61 * @hideinitializer 57 62 * Missing required header(s). 58 63 */ … … 98 103 */ 99 104 #define PJSIP_EINVALIDVIA (PJSIP_ERRNO_START_PJSIP + 9) 105 /** 106 * @hideinitializer 107 * Multiple Via headers in response. 108 */ 109 #define PJSIP_EMULTIPLEVIA (PJSIP_ERRNO_START_PJSIP + 9) 110 /** 111 * @hideinitializer 112 * SIP object is busy. 113 */ 114 #define PJSIP_EBUSY (PJSIP_ERRNO_START_PJSIP + 10) 115 /** 116 * @hideinitializer 117 * SIP object with the same type already exists. 118 */ 119 #define PJSIP_ETYPEEXISTS (PJSIP_ERRNO_START_PJSIP + 11) 120 100 121 101 122 -
pjproject/trunk/pjsip/include/pjsip/sip_misc.h
r51 r54 179 179 */ 180 180 PJ_DECL(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool, 181 const pjsip_transport _t*tr,181 const pjsip_transport *tr, 182 182 const pjsip_via_hdr *via, 183 183 pjsip_host_port *addr); -
pjproject/trunk/pjsip/include/pjsip/sip_private.h
r51 r54 36 36 37 37 38 /**39 * Create a new transport manager.40 * @param pool The pool41 * @param endpt The endpoint42 * @param cb Callback to be called to receive messages from transport.43 */44 PJ_DECL(pj_status_t) pjsip_transport_mgr_create( pj_pool_t *pool,45 pjsip_endpoint *endpt,46 void (*cb)(pjsip_endpoint *,47 pjsip_rx_data *),48 pjsip_transport_mgr **);49 50 51 /**52 * Destroy transport manager and release all transports.53 * @param mgr Transport manager to be destroyed.54 */55 PJ_DECL(pj_status_t) pjsip_transport_mgr_destroy( pjsip_transport_mgr *mgr );56 57 /**58 * Poll for transport events.59 * Incoming messages will be parsed by the transport manager, and the callback60 * will be called for each of this message.61 * @param endpt The endpoint.62 * @param timeout Timeout value, or NULL to wait forever.63 */64 PJ_DECL(int) pjsip_transport_mgr_handle_events( pjsip_transport_mgr *mgr,65 const pj_time_val *timeout );66 67 /**68 * Get the pointer to the first transport iterator.69 * @param mgr The transport manager.70 * @param it The iterator used for iterating the hash element.71 * @return the iterator to the first transport, or NULL.72 */73 PJ_DECL(pj_hash_iterator_t*) pjsip_transport_first( pjsip_transport_mgr *mgr,74 pj_hash_iterator_t *it );75 76 77 /**78 * Get the next transport iterator.79 * @param itr the iterator to the transport.80 * @return the iterator pointed to the next transport, or NULL.81 */82 PJ_DECL(pj_hash_iterator_t*) pjsip_transport_next( pjsip_transport_mgr *mgr,83 pj_hash_iterator_t *itr );84 85 /**86 * Get the value of transport iterator.87 * @param mgr the transport manager.88 * @param itr the transport iterator.89 * @return the transport associated with the iterator.90 */91 PJ_DECL(pjsip_transport_t*) pjsip_transport_this( pjsip_transport_mgr *mgr,92 pj_hash_iterator_t *itr );93 38 94 39 /** -
pjproject/trunk/pjsip/include/pjsip/sip_transaction.h
r51 r54 112 112 int current_addr; /**< Address currently used. */ 113 113 114 pjsip_transport _t*transport; /**< Transport to use. */114 pjsip_transport *transport; /**< Transport to use. */ 115 115 116 116 /* -
pjproject/trunk/pjsip/include/pjsip/sip_transport.h
r51 r54 30 30 #include <pj/list.h> 31 31 #include <pj/ioqueue.h> 32 #include <pj/timer.h> 32 33 33 34 PJ_BEGIN_DECL … … 43 44 * @{ 44 45 */ 46 47 /***************************************************************************** 48 * 49 * GENERAL TRANSPORT (NAMES, TYPES, ETC.) 50 * 51 *****************************************************************************/ 52 53 /** 54 * Flags for SIP transports. 55 */ 56 enum pjsip_transport_flags_e 57 { 58 PJSIP_TRANSPORT_RELIABLE = 1, /**< Transport is reliable. */ 59 PJSIP_TRANSPORT_SECURE = 2, /**< Transport is secure. */ 60 PJSIP_TRANSPORT_DATAGRAM = 4, /**< Datagram based transport. */ 61 }; 62 63 /** 64 * Check if transport tp is reliable. 65 */ 66 #define PJSIP_TRANSPORT_IS_RELIABLE(tp) \ 67 ((tp)->flag & PJSIP_TRANSPORT_RELIABLE) 68 69 /** 70 * Get the transport type from the transport name. 71 * 72 * @param name Transport name, such as "TCP", or "UDP". 73 * 74 * @return The transport type, or PJSIP_TRANSPORT_UNSPECIFIED if 75 * the name is not recognized as the name of supported 76 * transport. 77 */ 78 PJ_DECL(pjsip_transport_type_e) 79 pjsip_transport_get_type_from_name(const pj_str_t *name); 80 81 /** 82 * Get the transport type for the specified flags. 83 * 84 * @param flag The transport flag. 85 * 86 * @return Transport type. 87 */ 88 PJ_DECL(pjsip_transport_type_e) 89 pjsip_transport_get_type_from_flag(unsigned flag); 90 91 /** 92 * Get transport flag from type. 93 * 94 * @param type Transport type. 95 * 96 * @return Transport flags. 97 */ 98 PJ_DECL(unsigned) 99 pjsip_transport_get_flag_from_type( pjsip_transport_type_e type ); 100 101 /** 102 * Get the default SIP port number for the specified type. 103 * 104 * @param type Transport type. 105 * 106 * @return The port number, which is the default SIP port number for 107 * the specified type. 108 */ 109 PJ_DECL(int) 110 pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type); 111 112 113 /***************************************************************************** 114 * 115 * RECEIVE DATA BUFFER. 116 * 117 *****************************************************************************/ 45 118 46 119 /** … … 53 126 struct pjsip_rx_data 54 127 { 55 //PJ_DECL_LIST_MEMBER(struct pjsip_rx_data); 56 57 /** Memory pool for this buffer. */ 58 pj_pool_t *pool; 59 60 /** Ioqueue op key. */ 61 pj_ioqueue_op_key_t op_key; 62 63 /** Time when the message was received. */ 64 pj_time_val timestamp; 65 66 /** The packet buffer. */ 67 char packet[PJSIP_MAX_PKT_LEN]; 68 69 /** The length of the packet received. */ 70 int len; 71 72 /** The source address from which the packet was received. */ 73 pj_sockaddr_in addr; 74 75 /** The length of the source address. */ 76 int addr_len; 77 78 /** The transport object which received this packet. */ 79 pjsip_transport_t *transport; 80 81 /** The parsed message, if any. */ 82 pjsip_msg *msg; 83 84 /** This the transaction key generated from the message. This key is only 85 * available after the rdata has reached the endpoint. 86 */ 87 pj_str_t key; 88 89 /** The Call-ID header as found in the message. */ 90 pj_str_t call_id; 91 92 /** The From header as found in the message. */ 93 pjsip_from_hdr *from; 94 95 /** The To header as found in the message. */ 96 pjsip_to_hdr *to; 97 98 /** The topmost Via header as found in the message. */ 99 pjsip_via_hdr *via; 100 101 /** The CSeq header as found in the message. */ 102 pjsip_cseq_hdr *cseq; 103 104 /** Max forwards header. */ 105 pjsip_max_forwards_hdr *max_fwd; 106 107 /** The first route header. */ 108 pjsip_route_hdr *route; 109 110 /** The first record-route header. */ 111 pjsip_rr_hdr *record_route; 112 113 /** Content-type header. */ 114 pjsip_ctype_hdr *ctype; 115 116 /** Content-length header. */ 117 pjsip_clen_hdr *clen; 118 119 /** The first Require header. */ 120 pjsip_require_hdr *require; 121 122 /** The list of error generated by the parser when parsing this message. */ 123 pjsip_parser_err_report parse_err; 128 129 /** 130 * tp_info is part of rdata that remains static for the duration of the 131 * buffer. It is initialized when the buffer was created by transport. 132 */ 133 struct 134 { 135 /** Memory pool for this buffer. */ 136 pj_pool_t *pool; 137 138 /** The transport object which received this packet. */ 139 pjsip_transport *transport; 140 141 /** Ioqueue key. */ 142 pj_ioqueue_op_key_t op_key; 143 144 } tp_info; 145 146 147 /** 148 * pkt_info is initialized by transport when it receives an incoming 149 * packet. 150 */ 151 struct 152 { 153 /** Time when the message was received. */ 154 pj_time_val timestamp; 155 156 /** Pointer to the original packet. */ 157 char packet[PJSIP_MAX_PKT_LEN]; 158 159 /** Zero termination for the packet. */ 160 pj_uint32_t zero; 161 162 /** The length of the packet received. */ 163 int len; 164 165 /** The source address from which the packet was received. */ 166 pj_sockaddr_in addr; 167 168 /** The length of the source address. */ 169 int addr_len; 170 171 } pkt_info; 172 173 174 /** 175 * msg_info is initialized by transport mgr (tpmgr) before this buffer 176 * is passed to endpoint. 177 */ 178 struct 179 { 180 /** Start of msg buffer. */ 181 char *msg_buf; 182 183 /** Length fo message. */ 184 int len; 185 186 /** The parsed message, if any. */ 187 pjsip_msg *msg; 188 189 /** The Call-ID header as found in the message. */ 190 pj_str_t call_id; 191 192 /** The From header as found in the message. */ 193 pjsip_from_hdr *from; 194 195 /** The To header as found in the message. */ 196 pjsip_to_hdr *to; 197 198 /** The topmost Via header as found in the message. */ 199 pjsip_via_hdr *via; 200 201 /** The CSeq header as found in the message. */ 202 pjsip_cseq_hdr *cseq; 203 204 /** Max forwards header. */ 205 pjsip_max_forwards_hdr *max_fwd; 206 207 /** The first route header. */ 208 pjsip_route_hdr *route; 209 210 /** The first record-route header. */ 211 pjsip_rr_hdr *record_route; 212 213 /** Content-type header. */ 214 pjsip_ctype_hdr *ctype; 215 216 /** Content-length header. */ 217 pjsip_clen_hdr *clen; 218 219 /** The first Require header. */ 220 pjsip_require_hdr *require; 221 222 /** The list of error generated by the parser when parsing 223 this message. 224 */ 225 pjsip_parser_err_report parse_err; 226 227 } msg_info; 228 229 230 /** 231 * endpt_info is initialized by endpoint after this buffer reaches 232 * endpoint. 233 */ 234 struct 235 { 236 /** 237 * This the transaction key generated for the message. 238 */ 239 pj_str_t key; 240 241 } endpt_info; 242 124 243 }; 125 244 245 246 /***************************************************************************** 247 * 248 * TRANSMIT DATA BUFFER MANIPULATION. 249 * 250 *****************************************************************************/ 126 251 127 252 /** … … 157 282 158 283 /** The transport manager for this buffer. */ 159 pjsip_t ransport_mgr*mgr;284 pjsip_tpmgr *mgr; 160 285 161 286 /** Ioqueue asynchronous operation key. */ 162 287 pj_ioqueue_op_key_t op_key; 288 289 /** Lock object. */ 290 pj_lock_t *lock; 163 291 164 292 /** The message in this buffer. */ … … 175 303 /** Reference counter. */ 176 304 pj_atomic_t *ref_cnt; 305 306 /** Being sent? */ 307 int is_pending; 308 309 /** Transport internal. */ 310 void *token; 311 void (*cb)(void*, pjsip_tx_data*, pj_status_t); 177 312 }; 178 313 314 315 /** 316 * Create a new, blank transmit buffer. The reference count is initialized 317 * to zero. 318 * 319 * @param mgr The transport manager. 320 * @param tdata Pointer to receive transmit data. 321 * 322 * @return PJ_SUCCESS, or the appropriate error code. 323 * 324 * @see pjsip_endpt_create_tdata 325 */ 326 pj_status_t pjsip_tx_data_create( pjsip_tpmgr *mgr, 327 pjsip_tx_data **tdata ); 179 328 180 329 /** … … 194 343 */ 195 344 PJ_DECL(void) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata ); 345 346 /** 347 * Check if transmit data buffer contains a valid message. 348 * 349 * @param tdata The transmit buffer. 350 */ 351 PJ_DECL(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata ); 196 352 197 353 /** … … 208 364 209 365 210 /** 211 * Flags for SIP transports. 212 */ 213 enum pjsip_transport_flags_e 366 /***************************************************************************** 367 * 368 * TRANSPORT 369 * 370 *****************************************************************************/ 371 372 /** 373 * This structure represent the "public" interface of a SIP transport. 374 * Applications normally extend this structure to include transport 375 * specific members. 376 */ 377 typedef struct pjsip_transport 214 378 { 215 PJSIP_TRANSPORT_RELIABLE = 1, /**< Transport is reliable. */ 216 PJSIP_TRANSPORT_SECURE = 2, /**< Transport is secure. */ 217 PJSIP_TRANSPORT_IOQUEUE_BUSY = 4, /**< WTH?? */ 379 char obj_name[PJ_MAX_OBJ_NAME]; /**< Name. */ 380 381 pj_pool_t *pool; /**< Pool used by transport. */ 382 pj_atomic_t *ref_cnt; /**< Reference counter. */ 383 pj_lock_t *lock; /**< Lock object. */ 384 int tracing; /**< Tracing enabled? */ 385 386 pjsip_transport_type_e type; /**< Transport type. */ 387 char type_name[8]; /**< Type name. */ 388 unsigned flag; /**< #pjsip_transport_flags_e */ 389 390 pj_sockaddr_in local_addr; /**< Bound address. */ 391 pj_sockaddr_in public_addr; /**< STUN addres. */ 392 pj_sockaddr_in rem_addr; /**< Remote addr (zero for UDP) */ 393 394 pjsip_tpmgr *tpmgr; /**< Transport manager. */ 395 pj_timer_entry idle_timer; /**< Timer when ref cnt is zero.*/ 396 397 /** 398 * Function to be called by transport manager to send SIP message. 399 * 400 * @param transport The transport to send the message. 401 * @param packet The buffer to send. 402 * @param length The length of the buffer to send. 403 * @param op_key Completion token, which will be supplied to 404 * caller when pending send operation completes. 405 * @param rem_addr The remote destination address. 406 * @param callback If supplied, the callback will be called 407 * once a pending transmission has completed. If 408 * the function completes immediately (i.e. return 409 * code is not PJ_EPENDING), the callback will not 410 * be called. 411 * 412 * @return Should return PJ_SUCCESS only if data has been 413 * succesfully queued to operating system for 414 * transmission. Otherwise it may return PJ_EPENDING 415 * if the underlying transport can not send the 416 * data immediately and will send it later, which in 417 * this case caller doesn't have to do anything 418 * except wait the calback to be called, if it 419 * supplies one. 420 * Other return values indicate the error code. 421 */ 422 pj_status_t (*send_msg)(pjsip_transport *transport, 423 const void *packet, 424 pj_size_t length, 425 pj_ioqueue_op_key_t *op_key, 426 const pj_sockaddr_in *rem_addr, 427 void *token, 428 void (*callback)(pjsip_transport *transport, 429 void *token, 430 pj_status_t status)); 431 432 /** 433 * Destroy this transport. 434 */ 435 pj_status_t (*destroy)(pjsip_transport *transport); 436 437 /* 438 * Application may extend this structure.. 439 */ 440 } pjsip_transport; 441 442 443 /** 444 * Register a transport. 445 */ 446 PJ_DECL(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr, 447 pjsip_transport *tp ); 448 449 450 /** 451 * Unregister transport. This will eventually call the transport to 452 * destroy itself. 453 */ 454 PJ_DECL(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 455 pjsip_transport *tp); 456 457 /** 458 * Add ref. 459 */ 460 PJ_DECL(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp ); 461 462 /** 463 * Dec ref. 464 */ 465 PJ_DECL(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp ); 466 467 468 /** 469 * Call for incoming message. 470 */ 471 PJ_DECL(pj_ssize_t) pjsip_tpmgr_receive_packet(pjsip_tpmgr *mgr, 472 pjsip_rx_data *rdata); 473 474 475 /***************************************************************************** 476 * 477 * TRANSPORT FACTORY 478 * 479 *****************************************************************************/ 480 481 482 /** 483 * Transport factory. 484 */ 485 typedef struct pjsip_tpfactory pjsip_tpfactory; 486 487 /** 488 * Transport factory. 489 */ 490 struct pjsip_tpfactory 491 { 492 /* This list is managed by transport manager. */ 493 PJ_DECL_LIST_MEMBER(struct pjsip_tpfactory); 494 495 pj_pool_t *pool; 496 pj_lock_t *lock; 497 498 pjsip_transport_type_e type; 499 char type_name[8]; 500 unsigned flag; 501 502 pj_sockaddr_in local_addr; 503 pj_sockaddr_in public_addr; 504 505 /** 506 * Create new outbound connection. 507 */ 508 pj_status_t (*create_transport)(pjsip_tpfactory *factory, 509 pjsip_tpmgr *mgr, 510 pjsip_endpoint *endpt, 511 pj_ioqueue_t *ioqueue, 512 const pj_sockaddr_in *rem_addr, 513 pjsip_transport **transport); 514 515 /* 516 * Application may extend this structure.. 517 */ 218 518 }; 219 519 220 /** 221 * Get the transport type from the transport name. 222 * 223 * @param name Transport name, such as "TCP", or "UDP". 224 * 225 * @return The transport type, or PJSIP_TRANSPORT_UNSPECIFIED if 226 * the name is not recognized as the name of supported 227 * transport. 228 */ 229 PJ_DECL(pjsip_transport_type_e) 230 pjsip_transport_get_type_from_name(const pj_str_t *name); 231 232 /** 233 * Get the transport type for the specified flags. 234 * 235 * @param flag The transport flag. 236 * 237 * @return Transport type. 238 */ 239 PJ_DECL(pjsip_transport_type_e) 240 pjsip_transport_get_type_from_flag(unsigned flag); 241 242 /** 243 * Get the default SIP port number for the specified type. 244 * 245 * @param type Transport type. 246 * 247 * @return The port number, which is the default SIP port number for 248 * the specified type. 249 */ 250 PJ_DECL(int) 251 pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type); 252 253 254 /** 255 * Add reference to transport. 256 * Transactions or dialogs that uses a particular transport must call this 257 * function to indicate that the transport is being used, thus preventing the 258 * transport from being closed. 259 * 260 * @param transport The transport. 261 */ 262 PJ_DECL(void) 263 pjsip_transport_add_ref( pjsip_transport_t *transport ); 264 265 /** 266 * Decrease reference to transport. 267 * When the transport reference counter becomes zero, a timer will be started 268 * and when this timer expires and the reference counter is still zero, the 269 * transport will be released. 270 * 271 * @param transport The transport 272 */ 273 PJ_DECL(void) 274 pjsip_transport_dec_ref( pjsip_transport_t *transport ); 275 276 277 /** 278 * Macro to check whether the transport is reliable. 279 * 280 * @param transport The transport 281 * 282 * @return non-zero (not necessarily 1) if transport is reliable. 283 */ 284 #define PJSIP_TRANSPORT_IS_RELIABLE(transport) \ 285 (pjsip_transport_get_flag(transport) & PJSIP_TRANSPORT_RELIABLE) 286 287 288 /** 289 * Macro to check whether the transport is secure. 290 * 291 * @param transport The transport 292 * 293 * @return non-zero (not necessarily one) if transport is secure. 294 */ 295 #define PJSIP_TRANSPORT_IS_SECURE(transport) \ 296 (pjsip_transport_get_flag(transport) & PJSIP_TRANSPORT_SECURE) 297 298 /** 299 * Get the transport type. 300 * 301 * @param tr The transport. 302 * 303 * @return Transport type. 304 */ 305 PJ_DECL(pjsip_transport_type_e) 306 pjsip_transport_get_type( const pjsip_transport_t * tr); 307 308 /** 309 * Get the transport type name (ie "UDP", or "TCP"). 310 * 311 * @param tr The transport. 312 * @return The string type. 313 */ 314 PJ_DECL(const char *) 315 pjsip_transport_get_type_name( const pjsip_transport_t * tr); 316 317 /** 318 * Get the transport's object name. 319 * 320 * @param tr The transport. 321 * @return The object name. 322 */ 323 PJ_DECL(const char*) 324 pjsip_transport_get_obj_name( const pjsip_transport_t *tr ); 325 326 /** 327 * Get the transport's reference counter. 328 * 329 * @param tr The transport. 330 * @return The reference count value. 331 */ 332 PJ_DECL(int) 333 pjsip_transport_get_ref_cnt( const pjsip_transport_t *tr ); 334 335 /** 336 * Get transport flag. 337 * 338 * @param tr The transport. 339 * @return Transport flag. 340 */ 341 PJ_DECL(unsigned) 342 pjsip_transport_get_flag( const pjsip_transport_t * tr ); 343 344 /** 345 * Get the local address of the transport, ie. the address which the socket 346 * is bound. 347 * 348 * @param tr The transport. 349 * @return The address. 350 */ 351 PJ_DECL(const pj_sockaddr_in *) 352 pjsip_transport_get_local_addr( pjsip_transport_t * tr ); 353 354 /** 355 * Get the address name of the transport. Address name can be an arbitrary 356 * address assigned to a transport. This is usefull for example when STUN 357 * is used, then the address name of an UDP transport can specify the public 358 * address of the transport. When the address name is not set, then value 359 * will be equal to the local/bound address. Application should normally 360 * prefer to use the address name instead of the local address. 361 * 362 * @param tr The transport. 363 * @return The address name. 364 */ 365 PJ_DECL(const pj_sockaddr_in*) 366 pjsip_transport_get_addr_name (pjsip_transport_t *tr); 367 368 /** 369 * Get the remote address of the transport. Not all transports will have 370 * a valid remote address. UDP transports, for example, will likely to have 371 * zero has their remote address, because UDP transport can be used to send 372 * and receive messages from multiple destinations. 373 * 374 * @param tr The transport. 375 * @return The address. 376 */ 377 PJ_DECL(const pj_sockaddr_in *) 378 pjsip_transport_get_remote_addr( const pjsip_transport_t * tr ); 379 380 /** 381 * Send a SIP message using the specified transport, to the address specified 382 * in the outgoing data. This function is only usefull for application when it 383 * wants to handle the message statelessly, because otherwise it should create 384 * a transaction and let the transaction handles the transmission of the 385 * message. 386 * 387 * This function will send the message immediately, so application must be 388 * sure that the transport is ready to do so before calling this function. 389 * 390 * @param tr The transport to send the message. 391 * @param tdata The outgoing message buffer. 392 * @param addr The remote address. 393 * @param sent If not null, it will be filled up with the length of 394 * data sent. 395 * 396 * @return PJ_SUCCESS on success, or the appropriate error code. 397 */ 398 PJ_DECL(pj_status_t) pjsip_transport_send_msg( pjsip_transport_t *tr, 399 pjsip_tx_data *tdata, 400 const pj_sockaddr_in *addr, 401 pj_ssize_t *sent); 520 521 522 /** 523 * Register a transport factory. 524 * 525 * @param mgr The transport manager. 526 * @param factory Transport factory. 527 * 528 * @return PJ_SUCCESS if listener was successfully created. 529 */ 530 PJ_DECL(pj_status_t) pjsip_tpmgr_register_tpfactory(pjsip_tpmgr *mgr, 531 pjsip_tpfactory *tpf); 532 533 /** 534 * Unregister factory. 535 */ 536 PJ_DECL(pj_status_t) pjsip_tpmgr_unregister_tpfactory(pjsip_tpmgr *mgr, 537 pjsip_tpfactory *tpf); 538 539 540 /***************************************************************************** 541 * 542 * TRANSPORT MANAGER 543 * 544 *****************************************************************************/ 545 546 /** 547 * Create a new transport manager. 548 * 549 * @param pool Pool. 550 * @param endpt Endpoint instance. 551 * @param cb Callback to receive incoming message. 552 * @param p_mgr Pointer to receive the new transport manager. 553 * 554 * @return PJ_SUCCESS or the appropriate error code on error. 555 */ 556 PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 557 pjsip_endpoint * endpt, 558 pj_ioqueue_t *ioqueue, 559 pj_timer_heap_t *timer_heap, 560 void (*cb)(pjsip_endpoint*, 561 pj_status_t, 562 pjsip_rx_data *), 563 pjsip_tpmgr **p_mgr); 564 565 566 /** 567 * Destroy transport manager. 568 */ 569 PJ_DECL(pj_status_t) pjsip_tpmgr_destroy(pjsip_tpmgr *mgr); 570 571 572 /** 573 * Dump transport info. 574 */ 575 PJ_DECL(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr); 576 577 578 /***************************************************************************** 579 * 580 * PUBLIC API 581 * 582 *****************************************************************************/ 583 584 585 /** 586 * Find transport to be used to send message to remote destination. If no 587 * suitable transport is found, a new one will be created. 588 */ 589 PJ_DECL(pj_status_t) pjsip_tpmgr_alloc_transport( pjsip_tpmgr *mgr, 590 pjsip_transport_type_e type, 591 const pj_sockaddr_in *remote, 592 pjsip_transport **p_transport ); 593 594 595 /** 596 * Send a SIP message using the specified transport. 597 */ 598 PJ_DECL(pj_status_t) pjsip_transport_send( pjsip_transport *tr, 599 pjsip_tx_data *tdata, 600 const pj_sockaddr_in *addr, 601 void *token, 602 void (*cb)(void *token, 603 pjsip_tx_data *tdata, 604 pj_status_t)); 402 605 403 606 … … 406 609 */ 407 610 408 /*409 * PRIVATE FUNCTIONS!!!410 *411 * These functions are normally to be used by endpoint. Application should412 * use the variant provided by the endpoint instance.413 *414 * Application normally wouldn't be able to call these functions because it415 * has no reference of the transport manager (the instance of the transport416 * manager is hidden by endpoint!).417 */418 419 /*420 * Create a new transmit buffer.421 *422 * @param mgr The transport manager.423 * @return The transmit buffer data, or NULL on error.424 */425 pj_status_t pjsip_tx_data_create( pjsip_transport_mgr *mgr,426 pjsip_tx_data **tdata );427 428 429 /**430 * Create listener.431 *432 * @param mgr The transport manager.433 * @param type Transport type.434 * @param local_addr The address to bind.435 * @param addr_name If not null, sets the address name. If NULL,436 * then the local address will be used.437 *438 * @return PJ_SUCCESS if listener was successfully created.439 */440 PJ_DECL(pj_status_t) pjsip_create_listener( pjsip_transport_mgr *mgr,441 pjsip_transport_type_e type,442 pj_sockaddr_in *local_addr,443 const pj_sockaddr_in *addr_name);444 445 446 /**447 * Create UDP listener.448 *449 * @param mgr The transport manager.450 * @param sock The UDP socket.451 * @param addr_name If not null, sets the address name. If NULL,452 * then the local address will be used.453 *454 * @return PJ_SUCCESS if listener was successfully created.455 */456 PJ_DECL(pj_status_t) pjsip_create_udp_listener( pjsip_transport_mgr *mgr,457 pj_sock_t sock,458 const pj_sockaddr_in *addr_name);459 460 /**461 * Type of function to receive asynchronous transport completion for462 * pjsip_transport_get() operation.463 *464 * @param tr The transport.465 * @param token Token registered previously.466 * @param status Status of operation.467 */468 typedef void pjsip_transport_completion_callback(pjsip_transport_t *tr,469 void *token,470 pj_status_t status);471 472 /**473 * Find transport to be used to send message to remote destination. If no474 * suitable transport is found, a new one will be created. If transport475 * can not be available immediately (for example, an outgoing TCP connec()),476 * then the caller will be notified later via the callback.477 *478 * @param mgr The transport manager.479 * @param pool Pool to allocate asychronous job (if required).480 * @param type The transport type.481 * @param remote The remote address.482 * @param token The token that will be passed to the callback.483 * @param cb The callback to be called to report the completion of484 * the operation.485 */486 PJ_DECL(void) pjsip_transport_get( pjsip_transport_mgr *mgr,487 pj_pool_t *pool,488 pjsip_transport_type_e type,489 const pj_sockaddr_in *remote,490 void *token,491 pjsip_transport_completion_callback *cb);492 611 493 612 PJ_END_DECL -
pjproject/trunk/pjsip/include/pjsip/sip_types.h
r51 r54 26 26 * Opaque data structure for transports (sip_transport.h). 27 27 */ 28 typedef struct pjsip_transport _t pjsip_transport_t;28 typedef struct pjsip_transport pjsip_transport; 29 29 30 30 /** 31 31 * Opaque data type for transport manager (sip_transport.h). 32 32 */ 33 typedef struct pjsip_t ransport_mgr pjsip_transport_mgr;33 typedef struct pjsip_tpmgr pjsip_tpmgr; 34 34 35 35 /** … … 44 44 PJSIP_TRANSPORT_UDP, 45 45 46 #if PJ_HAS_TCP47 46 /** TCP. */ 48 47 PJSIP_TRANSPORT_TCP, … … 53 52 /** SCTP. */ 54 53 PJSIP_TRANSPORT_SCTP, 55 #endif56 54 57 55 } pjsip_transport_type_e; -
pjproject/trunk/pjsip/src/pjsip-ua/sip_dialog.c
r51 r54 1080 1080 * We will rewrite the message with a new status code. 1081 1081 */ 1082 only if tdata is not pending!!! 1082 1083 tdata = dlg->invite_tsx->last_tx; 1083 1084 msg = tdata->msg; -
pjproject/trunk/pjsip/src/pjsip/sip_auth.c
r51 r54 36 36 37 37 /* A macro just to get rid of type mismatch between char and unsigned char */ 38 #define MD5_APPEND(pms,buf,len) md5_append(pms, (const unsigned char*)buf, len)38 #define MD5_APPEND(pms,buf,len) pj_md5_update(pms, (const pj_uint8_t*)buf, len) 39 39 40 40 /* Logging. */ … … 81 81 char ha2[MD5STRLEN]; 82 82 unsigned char digest[16]; 83 md5_state_t pms;83 pj_md5_context pms; 84 84 85 85 pj_assert(result->slen >= MD5STRLEN); … … 91 91 *** ha1 = MD5(username ":" realm ":" password) 92 92 ***/ 93 md5_init(&pms);93 pj_md5_init(&pms); 94 94 MD5_APPEND( &pms, cred_info->username.ptr, cred_info->username.slen); 95 95 MD5_APPEND( &pms, ":", 1); … … 97 97 MD5_APPEND( &pms, ":", 1); 98 98 MD5_APPEND( &pms, cred_info->data.ptr, cred_info->data.slen); 99 md5_finish(&pms, digest);99 pj_md5_final(&pms, digest); 100 100 101 101 digest2str(digest, ha1); … … 111 111 *** ha2 = MD5(method ":" req_uri) 112 112 ***/ 113 md5_init(&pms);113 pj_md5_init(&pms); 114 114 MD5_APPEND( &pms, method->ptr, method->slen); 115 115 MD5_APPEND( &pms, ":", 1); 116 116 MD5_APPEND( &pms, uri->ptr, uri->slen); 117 md5_finish(&pms, digest);117 pj_md5_final(&pms, digest); 118 118 digest2str(digest, ha2); 119 119 … … 127 127 *** response = MD5(ha1 ":" nonce ":" nc ":" cnonce ":" qop ":" ha2) 128 128 ***/ 129 md5_init(&pms);129 pj_md5_init(&pms); 130 130 MD5_APPEND( &pms, ha1, MD5STRLEN); 131 131 MD5_APPEND( &pms, ":", 1); … … 143 143 144 144 /* This is the final response digest. */ 145 md5_finish(&pms, digest);145 pj_md5_final(&pms, digest); 146 146 147 147 /* Convert digest to string and store in chal->response. */ … … 735 735 PJ_UNUSED_ARG(endpt); 736 736 737 pj_assert(rdata->msg ->type == PJSIP_RESPONSE_MSG);738 pj_assert(rdata->msg ->line.status.code == 401 ||739 rdata->msg ->line.status.code == 407 );737 pj_assert(rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG); 738 pj_assert(rdata->msg_info.msg->line.status.code == 401 || 739 rdata->msg_info.msg->line.status.code == 407 ); 740 740 741 741 /* 742 742 * Respond to each authentication challenge. 743 743 */ 744 hdr = rdata->msg ->hdr.next;745 while (hdr != &rdata->msg ->hdr) {744 hdr = rdata->msg_info.msg->hdr.next; 745 while (hdr != &rdata->msg_info.msg->hdr) { 746 746 pjsip_auth_session *sess; 747 747 const pjsip_www_authenticate_hdr *hchal; … … 751 751 while (hdr->type != PJSIP_H_WWW_AUTHENTICATE && 752 752 hdr->type != PJSIP_H_PROXY_AUTHENTICATE && 753 hdr != &rdata->msg ->hdr)753 hdr != &rdata->msg_info.msg->hdr) 754 754 { 755 755 hdr = hdr->next; 756 756 } 757 if (hdr == &rdata->msg ->hdr)757 if (hdr == &rdata->msg_info.msg->hdr) 758 758 break; 759 759 -
pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
r51 r54 33 33 #include <pj/assert.h> 34 34 #include <pj/errno.h> 35 35 #include <pj/lock.h> 36 36 37 37 #define PJSIP_EX_NO_MEMORY PJ_NO_MEMORY_EXCEPTION … … 64 64 65 65 /** Transport manager. */ 66 pjsip_transport_mgr *transport_mgr; 66 pjsip_tpmgr *transport_mgr; 67 68 /** Ioqueue. */ 69 pj_ioqueue_t *ioqueue; 67 70 68 71 /** DNS Resolver. */ … … 96 99 * Prototypes. 97 100 */ 98 static void endpt_transport_callback( pjsip_endpoint *, pjsip_rx_data *rdata ); 101 static void endpt_transport_callback(pjsip_endpoint*, 102 pj_status_t, pjsip_rx_data*); 99 103 100 104 … … 355 359 pjsip_endpoint *endpt; 356 360 pjsip_max_forwards_hdr *mf_hdr; 361 pj_lock_t *lock = NULL; 357 362 358 363 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create()")); … … 399 404 } 400 405 406 /* Set recursive lock for the timer heap. */ 407 status = pj_lock_create_recursive_mutex( endpt->pool, "edpt%p", &lock); 408 if (status != PJ_SUCCESS) { 409 goto on_error; 410 } 411 pj_timer_heap_set_lock(endpt->timer_heap, lock, PJ_TRUE); 412 413 /* Set maximum timed out entries to process in a single poll. */ 414 pj_timer_heap_set_max_timed_out_per_poll(endpt->timer_heap, 415 PJSIP_MAX_TIMED_OUT_ENTRIES); 416 417 /* Create ioqueue. */ 418 status = pj_ioqueue_create( endpt->pool, PJSIP_MAX_TRANSPORTS, &endpt->ioqueue); 419 if (status != PJ_SUCCESS) { 420 goto on_error; 421 } 422 401 423 /* Create transport manager. */ 402 status = pjsip_t ransport_mgr_create( endpt->pool,403 endpt,404 405 424 status = pjsip_tpmgr_create( endpt->pool, endpt, 425 endpt->ioqueue, endpt->timer_heap, 426 &endpt_transport_callback, 427 &endpt->transport_mgr); 406 428 if (status != PJ_SUCCESS) { 407 429 goto on_error; … … 446 468 on_error: 447 469 if (endpt->transport_mgr) { 448 pjsip_t ransport_mgr_destroy(endpt->transport_mgr);470 pjsip_tpmgr_destroy(endpt->transport_mgr); 449 471 endpt->transport_mgr = NULL; 450 472 } … … 471 493 472 494 /* Shutdown and destroy all transports. */ 473 pjsip_t ransport_mgr_destroy(endpt->transport_mgr);495 pjsip_tpmgr_destroy(endpt->transport_mgr); 474 496 475 497 /* Delete endpoint mutex. */ … … 533 555 const pj_time_val *max_timeout) 534 556 { 535 pj_time_val timeout;536 int i;557 /* timeout is 'out' var. This just to make compiler happy. */ 558 pj_time_val timeout = { 0, 0}; 537 559 538 560 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_handle_events()")); 539 561 540 562 /* Poll the timer. The timer heap has its own mutex for better 541 * granularity, so we don't need to lock end endpoint. We also keep 542 * polling the timer while we have events. 563 * granularity, so we don't need to lock end endpoint. 543 564 */ 544 timeout.sec = timeout.msec = 0; /* timeout is 'out' var. This just to make compiler happy. */ 545 for (i=0; i<10; ++i) { 546 if (pj_timer_heap_poll( endpt->timer_heap, &timeout ) < 1) 547 break; 548 } 565 timeout.sec = timeout.msec = 0; 566 pj_timer_heap_poll( endpt->timer_heap, &timeout ); 549 567 550 568 /* If caller specifies maximum time to wait, then compare the value with … … 555 573 } 556 574 557 /* Poll events in the transport manager. */558 pj sip_transport_mgr_handle_events( endpt->transport_mgr, &timeout);575 /* Poll ioqueue. */ 576 pj_ioqueue_poll( endpt->ioqueue, &timeout); 559 577 } 560 578 … … 659 677 { 660 678 pjsip_role_e role; 661 if (rdata->msg ->type == PJSIP_REQUEST_MSG) {679 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) { 662 680 role = PJSIP_ROLE_UAS; 663 681 } else { 664 682 role = PJSIP_ROLE_UAC; 665 683 } 666 pjsip_tsx_create_key(rdata-> pool, &rdata->key, role,667 &rdata-> cseq->method, rdata);684 pjsip_tsx_create_key(rdata->tp_info.pool, &rdata->endpt_info.key, role, 685 &rdata->msg_info.cseq->method, rdata); 668 686 } 669 687 … … 673 691 */ 674 692 static void endpt_transport_callback( pjsip_endpoint *endpt, 693 pj_status_t status, 675 694 pjsip_rx_data *rdata ) 676 695 { 677 pjsip_msg *msg = rdata->msg ;696 pjsip_msg *msg = rdata->msg_info.msg; 678 697 pjsip_transaction *tsx; 679 698 pj_bool_t a_new_transaction_just_been_created = PJ_FALSE; 680 699 681 700 PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata)); 701 702 if (status != PJ_SUCCESS) { 703 const char *src_addr = pj_inet_ntoa(rdata->pkt_info.addr.sin_addr); 704 int port = pj_ntohs(rdata->pkt_info.addr.sin_port); 705 PJSIP_ENDPT_LOG_ERROR((endpt, "transport", status, 706 "Src.addr=%s:%d, packet:--\n" 707 "%s\n" 708 "-- end of packet. Error", 709 src_addr, port, rdata->msg_info.msg_buf)); 710 return; 711 } 682 712 683 713 /* For response, check that the value in Via sent-by match the transport. … … 688 718 const pj_sockaddr_in *addr; 689 719 const char *addr_addr; 690 int port = rdata-> via->sent_by.port;720 int port = rdata->msg_info.via->sent_by.port; 691 721 pj_bool_t mismatch = PJ_FALSE; 692 722 if (port == 0) { 693 723 int type; 694 type = pjsip_transport_get_type(rdata->transport);724 type = rdata->tp_info.transport->type; 695 725 port = pjsip_transport_get_default_port_for_type(type); 696 726 } 697 addr = pjsip_transport_get_addr_name(rdata->transport);727 addr = &rdata->tp_info.transport->public_addr; 698 728 addr_addr = pj_inet_ntoa(addr->sin_addr); 699 if (pj_strcmp2(&rdata-> via->sent_by.host, addr_addr) != 0)729 if (pj_strcmp2(&rdata->msg_info.via->sent_by.host, addr_addr) != 0) 700 730 mismatch = PJ_TRUE; 701 731 else if (port != pj_ntohs(addr->sin_port)) { … … 707 737 * both the port in sent-by and rport. We try to be lenient here! 708 738 */ 709 if (rdata-> via->rport_param != pj_sockaddr_in_get_port(addr))739 if (rdata->msg_info.via->rport_param != pj_sockaddr_in_get_port(addr)) 710 740 mismatch = PJ_TRUE; 711 741 else { … … 730 760 /* Find the transaction for the received message. */ 731 761 PJ_LOG(5, (THIS_FILE, "finding tsx with key=%.*s", 732 rdata-> key.slen, rdata->key.ptr));762 rdata->endpt_info.key.slen, rdata->endpt_info.key.ptr)); 733 763 734 764 /* Start lock mutex in the endpoint. */ … … 736 766 737 767 /* Find the transaction in the hash table. */ 738 tsx = pj_hash_get( endpt->tsx_table, rdata-> key.ptr, rdata->key.slen );768 tsx = pj_hash_get( endpt->tsx_table, rdata->endpt_info.key.ptr, rdata->endpt_info.key.slen ); 739 769 740 770 /* Unlock mutex. */ … … 753 783 /* Inform TU about the 200 message, only if it's INVITE. */ 754 784 if (PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200) && 755 rdata-> cseq->method.id == PJSIP_INVITE_METHOD)785 rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD) 756 786 { 757 787 pjsip_event e; … … 777 807 * For non-ACK request message, create a new transaction. 778 808 */ 779 } else if (rdata->msg ->line.req.method.id != PJSIP_ACK_METHOD) {809 } else if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) { 780 810 781 811 pj_status_t status; … … 806 836 pjsip_tsx_on_rx_msg( tsx, rdata ); 807 837 808 } else if (rdata->msg ->line.req.method.id == PJSIP_ACK_METHOD) {838 } else if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) { 809 839 /* 810 840 * This is an ACK message, but the INVITE transaction could not … … 915 945 * Find/create transport. 916 946 */ 917 PJ_DEF(void) pjsip_endpt_get_transport( pjsip_endpoint *endpt, 918 pj_pool_t *pool, 919 pjsip_transport_type_e type, 920 const pj_sockaddr_in *remote, 921 void *token, 922 pjsip_transport_completion_callback *cb) 923 { 924 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_get_transport()")); 925 pjsip_transport_get( endpt->transport_mgr, pool, type, 926 remote, token, cb); 927 } 928 929 930 PJ_DEF(pj_status_t) pjsip_endpt_create_listener( pjsip_endpoint *endpt, 931 pjsip_transport_type_e type, 932 pj_sockaddr_in *addr, 933 const pj_sockaddr_in *addr_name) 934 { 935 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_listener()")); 936 return pjsip_create_listener( endpt->transport_mgr, type, addr, addr_name ); 937 } 938 939 PJ_DEF(pj_status_t) pjsip_endpt_create_udp_listener( pjsip_endpoint *endpt, 940 pj_sock_t sock, 941 const pj_sockaddr_in *addr_name) 942 { 943 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_udp_listener()")); 944 return pjsip_create_udp_listener( endpt->transport_mgr, sock, addr_name ); 945 } 947 PJ_DECL(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt, 948 pjsip_transport_type_e type, 949 const pj_sockaddr_in *remote, 950 pjsip_transport **p_transport) 951 { 952 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_alloc_transport()")); 953 return pjsip_tpmgr_alloc_transport( endpt->transport_mgr, type, remote, 954 p_transport); 955 } 956 946 957 947 958 PJ_DEF(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail ) … … 949 960 #if PJ_LOG_MAX_LEVEL >= 3 950 961 unsigned count; 951 pj_hash_iterator_t itr_val;952 pj_hash_iterator_t *itr;953 962 954 963 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_dump()")); … … 1015 1024 1016 1025 /* Transports. 1017 * Note: transport is not properly locked in this function.1018 * See pjsip_transport_first, pjsip_transport_next.1019 1026 */ 1020 itr = pjsip_transport_first( endpt->transport_mgr, &itr_val ); 1021 if (itr) { 1022 PJ_LOG(3, (THIS_FILE, " Dumping transports:")); 1023 1024 do { 1025 char src_addr[128], dst_addr[128]; 1026 int src_port, dst_port; 1027 const pj_sockaddr_in *addr; 1028 pjsip_transport_t *t; 1029 1030 t = pjsip_transport_this(endpt->transport_mgr, itr); 1031 addr = pjsip_transport_get_local_addr(t); 1032 pj_native_strcpy(src_addr, pj_inet_ntoa(addr->sin_addr)); 1033 src_port = pj_ntohs(addr->sin_port); 1034 1035 addr = pjsip_transport_get_remote_addr(t); 1036 pj_native_strcpy(dst_addr, pj_inet_ntoa(addr->sin_addr)); 1037 dst_port = pj_ntohs(addr->sin_port); 1038 1039 PJ_LOG(3, (THIS_FILE, " %s %s %s:%d --> %s:%d (refcnt=%d)", 1040 pjsip_transport_get_type_name(t), 1041 pjsip_transport_get_obj_name(t), 1042 src_addr, src_port, 1043 dst_addr, dst_port, 1044 pjsip_transport_get_ref_cnt(t))); 1045 1046 itr = pjsip_transport_next(endpt->transport_mgr, itr); 1047 } while (itr); 1048 } 1027 pjsip_tpmgr_dump_transports( endpt->transport_mgr ); 1049 1028 1050 1029 /* Timer. */ -
pjproject/trunk/pjsip/src/pjsip/sip_misc.c
r51 r54 430 430 431 431 /* rdata must be a request message. */ 432 req_msg = rdata->msg ;432 req_msg = rdata->msg_info.msg; 433 433 pj_assert(req_msg->type == PJSIP_REQUEST_MSG); 434 434 … … 450 450 451 451 /* Set TX data attributes. */ 452 tdata->rx_timestamp = rdata-> timestamp;452 tdata->rx_timestamp = rdata->pkt_info.timestamp; 453 453 454 454 /* Copy all the via headers, in order. */ 455 via = rdata-> via;455 via = rdata->msg_info.via; 456 456 while (via) { 457 457 pjsip_msg_add_hdr( msg, pjsip_hdr_clone(tdata->pool, via)); … … 479 479 480 480 /* Copy From header. */ 481 hdr = pjsip_hdr_clone(tdata->pool, rdata-> from);481 hdr = pjsip_hdr_clone(tdata->pool, rdata->msg_info.from); 482 482 pjsip_msg_add_hdr( msg, hdr); 483 483 484 484 /* Copy To header. */ 485 hdr = pjsip_hdr_clone(tdata->pool, rdata-> to);485 hdr = pjsip_hdr_clone(tdata->pool, rdata->msg_info.to); 486 486 pjsip_msg_add_hdr( msg, hdr); 487 487 488 488 /* Copy CSeq header. */ 489 hdr = pjsip_hdr_clone(tdata->pool, rdata-> cseq);489 hdr = pjsip_hdr_clone(tdata->pool, rdata->msg_info.cseq); 490 490 pjsip_msg_add_hdr( msg, hdr); 491 491 … … 515 515 516 516 /* rdata must be a final response. */ 517 pj_assert(rdata->msg ->type==PJSIP_RESPONSE_MSG &&518 rdata->msg ->line.status.code >= 300);517 pj_assert(rdata->msg_info.msg->type==PJSIP_RESPONSE_MSG && 518 rdata->msg_info.msg->line.status.code >= 300); 519 519 520 520 /* Log this action. */ … … 543 543 to = (pjsip_to_hdr*)pjsip_msg_find_remove_hdr( invite_msg, 544 544 PJSIP_H_TO, NULL); 545 pj_strdup(tdata->pool, &to->tag, &rdata-> to->tag);545 pj_strdup(tdata->pool, &to->tag, &rdata->msg_info.to->tag); 546 546 pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*)to ); 547 547 … … 675 675 */ 676 676 PJ_DEF(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool, 677 const pjsip_transport _t*req_transport,677 const pjsip_transport *req_transport, 678 678 const pjsip_via_hdr *via, 679 679 pjsip_host_port *send_addr) … … 688 688 * - otherwise send to the address in sent-by. 689 689 */ 690 send_addr->flag = pjsip_transport_get_flag(req_transport);691 send_addr->type = pjsip_transport_get_type(req_transport);690 send_addr->flag = req_transport->flag; 691 send_addr->type = req_transport->type; 692 692 693 693 if (PJSIP_TRANSPORT_IS_RELIABLE(req_transport)) { 694 694 const pj_sockaddr_in *remote_addr; 695 remote_addr = pjsip_transport_get_remote_addr(req_transport);695 remote_addr = &req_transport->rem_addr; 696 696 pj_strdup2(pool, &send_addr->host, 697 697 pj_inet_ntoa(remote_addr->sin_addr)); -
pjproject/trunk/pjsip/src/pjsip/sip_parser.c
r51 r54 559 559 560 560 context.scanner = &scanner; 561 context.pool = rdata-> pool;561 context.pool = rdata->tp_info.pool; 562 562 context.rdata = rdata; 563 563 564 564 PJ_TRY { 565 rdata->msg = int_parse_msg(&context, &rdata->parse_err);565 rdata->msg_info.msg = int_parse_msg(&context, &rdata->msg_info.parse_err); 566 566 } 567 567 PJ_DEFAULT { 568 rdata->msg = NULL;568 rdata->msg_info.msg = NULL; 569 569 } 570 570 PJ_END 571 571 572 572 pj_scan_fini(&scanner); 573 return rdata->msg ;573 return rdata->msg_info.msg; 574 574 } 575 575 … … 1259 1259 1260 1260 if (ctx->rdata) 1261 ctx->rdata-> call_id = hdr->id;1261 ctx->rdata->msg_info.call_id = hdr->id; 1262 1262 1263 1263 return (pjsip_hdr*)hdr; … … 1340 1340 1341 1341 if (ctx->rdata) 1342 ctx->rdata-> clen = hdr;1342 ctx->rdata->msg_info.clen = hdr; 1343 1343 1344 1344 return (pjsip_hdr*)hdr; … … 1368 1368 1369 1369 if (ctx->rdata) 1370 ctx->rdata-> ctype = hdr;1370 ctx->rdata->msg_info.ctype = hdr; 1371 1371 1372 1372 return (pjsip_hdr*)hdr; … … 1389 1389 1390 1390 if (ctx->rdata) 1391 ctx->rdata-> cseq = hdr;1391 ctx->rdata->msg_info.cseq = hdr; 1392 1392 1393 1393 return (pjsip_hdr*)hdr; … … 1433 1433 parse_hdr_fromto(ctx->scanner, ctx->pool, hdr); 1434 1434 if (ctx->rdata) 1435 ctx->rdata-> from = hdr;1435 ctx->rdata->msg_info.from = hdr; 1436 1436 1437 1437 return (pjsip_hdr*)hdr; … … 1444 1444 parse_generic_array_hdr(hdr, ctx->scanner); 1445 1445 1446 if (ctx->rdata && ctx->rdata-> require == NULL)1447 ctx->rdata-> require = hdr;1446 if (ctx->rdata && ctx->rdata->msg_info.require == NULL) 1447 ctx->rdata->msg_info.require = hdr; 1448 1448 1449 1449 return (pjsip_hdr*)hdr; … … 1475 1475 1476 1476 if (ctx->rdata) 1477 ctx->rdata-> to = hdr;1477 ctx->rdata->msg_info.to = hdr; 1478 1478 1479 1479 return (pjsip_hdr*)hdr; … … 1529 1529 1530 1530 if (ctx->rdata) 1531 ctx->rdata->m ax_fwd = hdr;1531 ctx->rdata->msg_info.max_fwd = hdr; 1532 1532 1533 1533 return (pjsip_hdr*)hdr; … … 1579 1579 parse_hdr_end(scanner); 1580 1580 1581 if (ctx->rdata && ctx->rdata-> record_route==NULL)1582 ctx->rdata-> record_route = first;1581 if (ctx->rdata && ctx->rdata->msg_info.record_route==NULL) 1582 ctx->rdata->msg_info.record_route = first; 1583 1583 1584 1584 return (pjsip_hdr*)first; … … 1607 1607 parse_hdr_end(scanner); 1608 1608 1609 if (ctx->rdata && ctx->rdata-> route==NULL)1610 ctx->rdata-> route = first;1609 if (ctx->rdata && ctx->rdata->msg_info.route==NULL) 1610 ctx->rdata->msg_info.route = first; 1611 1611 1612 1612 return (pjsip_hdr*)first; … … 1660 1660 parse_hdr_end(scanner); 1661 1661 1662 if (ctx->rdata && ctx->rdata-> via == NULL)1663 ctx->rdata-> via = first;1662 if (ctx->rdata && ctx->rdata->msg_info.via == NULL) 1663 ctx->rdata->msg_info.via = first; 1664 1664 1665 1665 return (pjsip_hdr*)first; -
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r51 r54 193 193 194 194 PJ_ASSERT_RETURN(pool && str && method && rdata, PJ_EINVAL); 195 PJ_ASSERT_RETURN(rdata->msg , PJ_EINVAL);196 PJ_ASSERT_RETURN(rdata-> via, PJSIP_EMISSINGHDR);197 PJ_ASSERT_RETURN(rdata-> cseq, PJSIP_EMISSINGHDR);198 PJ_ASSERT_RETURN(rdata-> from, PJSIP_EMISSINGHDR);199 200 host = &rdata-> via->sent_by.host;201 req_uri = (pjsip_uri*)rdata->msg ->line.req.uri;195 PJ_ASSERT_RETURN(rdata->msg_info.msg, PJ_EINVAL); 196 PJ_ASSERT_RETURN(rdata->msg_info.via, PJSIP_EMISSINGHDR); 197 PJ_ASSERT_RETURN(rdata->msg_info.cseq, PJSIP_EMISSINGHDR); 198 PJ_ASSERT_RETURN(rdata->msg_info.from, PJSIP_EMISSINGHDR); 199 200 host = &rdata->msg_info.via->sent_by.host; 201 req_uri = (pjsip_uri*)rdata->msg_info.msg->line.req.uri; 202 202 203 203 /* Calculate length required. */ 204 204 len_required = 9 + /* CSeq number */ 205 rdata-> from->tag.slen + /* From tag. */206 rdata-> call_id.slen + /* Call-ID */205 rdata->msg_info.from->tag.slen + /* From tag. */ 206 rdata->msg_info.call_id.slen + /* Call-ID */ 207 207 host->slen + /* Via host. */ 208 208 9 + /* Via port. */ … … 232 232 233 233 /* Add CSeq (only the number). */ 234 len = pj_utoa(rdata-> cseq->cseq, p);234 len = pj_utoa(rdata->msg_info.cseq->cseq, p); 235 235 p += len; 236 236 *p++ = SEPARATOR; 237 237 238 238 /* Add From tag. */ 239 len = rdata-> from->tag.slen;240 pj_memcpy( p, rdata-> from->tag.ptr, len);239 len = rdata->msg_info.from->tag.slen; 240 pj_memcpy( p, rdata->msg_info.from->tag.ptr, len); 241 241 p += len; 242 242 *p++ = SEPARATOR; 243 243 244 244 /* Add Call-ID. */ 245 len = rdata-> call_id.slen;246 pj_memcpy( p, rdata-> call_id.ptr, len );245 len = rdata->msg_info.call_id.slen; 246 pj_memcpy( p, rdata->msg_info.call_id.ptr, len ); 247 247 p += len; 248 248 *p++ = SEPARATOR; … … 258 258 *p++ = ':'; 259 259 260 len = pj_utoa(rdata-> via->sent_by.port, p);260 len = pj_utoa(rdata->msg_info.via->sent_by.port, p); 261 261 p += len; 262 262 *p++ = SEPARATOR; … … 325 325 * handled as RFC2543. 326 326 */ 327 const pj_str_t *branch = &rdata-> via->branch_param;327 const pj_str_t *branch = &rdata->msg_info.via->branch_param; 328 328 329 329 if (pj_strncmp(branch,&rfc3261_branch,PJSIP_RFC3261_BRANCH_LEN)==0) { … … 643 643 * has completed, with or without error. 644 644 */ 645 static void tsx_transport_callback(pjsip_transport _t*tr,645 static void tsx_transport_callback(pjsip_transport *tr, 646 646 void *token, 647 647 pj_status_t status) … … 657 657 if (status == PJ_SUCCESS) { 658 658 PJ_LOG(4, (tsx->obj_name, "%s connected to %s:%d", 659 pjsip_transport_get_type_name(tr),659 tr->type_name, 660 660 addr, tsx->dest_name.port)); 661 661 } else { 662 662 PJ_LOG(4, (tsx->obj_name, "%s unable to connect to %s:%d, status=%d", 663 pjsip_transport_get_type_name(tr),663 tr->type_name, 664 664 addr, tsx->dest_name.port, status)); 665 665 } … … 878 878 pjsip_rx_data *rdata) 879 879 { 880 pjsip_msg *msg = rdata->msg ;880 pjsip_msg *msg = rdata->msg_info.msg; 881 881 pj_str_t *branch; 882 882 pjsip_cseq_hdr *cseq; … … 890 890 891 891 /* Keep shortcut to message */ 892 msg = rdata->msg ;892 msg = rdata->msg_info.msg; 893 893 894 894 /* Role is UAS */ … … 909 909 910 910 /* Duplicate branch parameter for transaction. */ 911 branch = &rdata-> via->branch_param;911 branch = &rdata->msg_info.via->branch_param; 912 912 pj_strdup(tsx->pool, &tsx->branch, branch); 913 913 … … 916 916 917 917 /* Save CSeq */ 918 cseq = rdata-> cseq;918 cseq = rdata->msg_info.cseq; 919 919 tsx->cseq = cseq->cseq; 920 920 … … 932 932 * then return the response using the same transport. 933 933 */ 934 if (PJSIP_TRANSPORT_IS_RELIABLE(rdata->t ransport) ||935 rdata-> via->rport_param >= 0)934 if (PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport) || 935 rdata->msg_info.via->rport_param >= 0) 936 936 { 937 tsx->transport = rdata->t ransport;937 tsx->transport = rdata->tp_info.transport; 938 938 pjsip_transport_add_ref(tsx->transport); 939 939 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; … … 944 944 pjsip_transport_get_type(tsx->transport); 945 945 pj_memcpy(&tsx->remote_addr.entry[0].addr, 946 &rdata-> addr, rdata->addr_len);946 &rdata->pkt_info.addr, rdata->pkt_info.addr_len); 947 947 948 948 } else { 949 949 pj_status_t status; 950 950 951 status = pjsip_get_response_addr(tsx->pool, rdata->t ransport,952 rdata-> via, &tsx->dest_name);951 status = pjsip_get_response_addr(tsx->pool, rdata->tp_info.transport, 952 rdata->msg_info.via, &tsx->dest_name); 953 953 if (status != PJ_SUCCESS) { 954 954 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; … … 1213 1213 /* Don't update Via sent-by on retransmission. */ 1214 1214 if (via->sent_by.host.slen == 0) { 1215 addr_name = pjsip_transport_get_addr_name(tsx->transport);1215 addr_name = &tsx->transport->public_addr; 1216 1216 pj_strdup2(tdata->pool, &via->transport, 1217 pjsip_transport_get_type_name(tsx->transport));1217 tsx->transport->type_name); 1218 1218 pj_strdup2(tdata->pool, &via->sent_by.host, 1219 1219 pj_inet_ntoa(addr_name->sin_addr)); … … 1397 1397 */ 1398 1398 /* Keep last_tx for authorization. */ 1399 code = event->body.rx_msg.rdata->msg ->line.status.code;1399 code = event->body.rx_msg.rdata->msg_info.msg->line.status.code; 1400 1400 if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) { 1401 1401 pjsip_tx_data_dec_ref(tsx->last_tx); … … 1666 1666 } 1667 1667 1668 tsx->status_code = event->body.rx_msg.rdata->msg ->line.status.code;1668 tsx->status_code = event->body.rx_msg.rdata->msg_info.msg->line.status.code; 1669 1669 } else { 1670 1670 tsx->status_code = PJSIP_SC_TSX_TIMEOUT; … … 1763 1763 1764 1764 if (event->type == PJSIP_EVENT_RX_MSG) { 1765 pjsip_msg *msg = event->body.rx_msg.rdata->msg ;1765 pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg; 1766 1766 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, NULL ); 1767 1767 … … 1856 1856 * TU doesn't need to be informed. 1857 1857 */ 1858 pjsip_msg *msg = event->body.rx_msg.rdata->msg ;1858 pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg; 1859 1859 pj_assert(msg->type == PJSIP_RESPONSE_MSG); 1860 1860 if (msg->type==PJSIP_RESPONSE_MSG && … … 1922 1922 1923 1923 pjsip_method_e method_id = 1924 event->body.rx_msg.rdata->msg ->line.req.method.id;1924 event->body.rx_msg.rdata->msg_info.msg->line.req.method.id; 1925 1925 1926 1926 /* Must be a request message. */ 1927 pj_assert(event->body.rx_msg.rdata->msg ->type == PJSIP_REQUEST_MSG);1927 pj_assert(event->body.rx_msg.rdata->msg_info.msg->type == PJSIP_REQUEST_MSG); 1928 1928 1929 1929 /* Must be an ACK request or a late INVITE retransmission. */ -
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r51 r54 30 30 #include <pj/pool.h> 31 31 #include <pj/assert.h> 32 33 #define MGR_IDLE_CHECK_INTERVAL 30 34 #define MGR_HASH_TABLE_SIZE PJSIP_MAX_DIALOG_COUNT 35 #define BACKLOG 5 36 #define DEFAULT_SO_SNDBUF (8 * 1024 * 1024) 37 #define DEFAULT_SO_RCVBUF (8 * 1024 * 1024) 38 39 #define LOG_TRANSPORT_MGR "trmgr" 40 #define THIS_FILE "sip_transport" 41 42 static void destroy_transport( pjsip_transport_mgr *mgr, pjsip_transport_t *tr ); 43 44 45 /** 46 * New TCP socket for accept. 47 */ 48 typedef struct incoming_socket_rec 49 { 50 pj_sock_t sock; 51 pj_sockaddr_in remote; 52 pj_sockaddr_in local; 53 int addrlen; 54 } incoming_socket_rec; 55 56 /** 57 * SIP Transport. 58 */ 59 struct pjsip_transport_t 60 { 61 /** Standard list members, for chaining the transport in the 62 * listener list. 63 */ 64 PJ_DECL_LIST_MEMBER(struct pjsip_transport_t); 65 66 /** Transport's pool. */ 67 pj_pool_t *pool; 68 69 /** Mutex */ 70 pj_mutex_t *tr_mutex; 71 72 /** Transport name for logging purpose */ 73 char obj_name[PJ_MAX_OBJ_NAME]; 74 75 /** Socket handle */ 76 pj_sock_t sock; 77 78 /** Transport type. */ 79 pjsip_transport_type_e type; 80 81 /** Flags to keep various states (see pjsip_transport_flags_e). */ 82 pj_uint32_t flag; 83 84 /** I/O Queue key */ 85 pj_ioqueue_key_t *key; 86 87 /** Accept key. */ 88 pj_ioqueue_op_key_t accept_op; 89 90 /** Receive data buffer */ 91 pjsip_rx_data *rdata; 92 93 /** Pointer to transport manager */ 94 pjsip_transport_mgr *mgr; 95 96 /** Reference counter, to prevent this transport from being closed while 97 * it's being used. 98 */ 99 pj_atomic_t *ref_cnt; 100 101 /** Local address. */ 102 pj_sockaddr_in local_addr; 103 104 /** Address name (what to put in Via address field). */ 105 pj_sockaddr_in addr_name; 106 107 /** Remote address (can be zero for UDP and for listeners). UDP listener 108 * bound to local loopback interface (127.0.0.1) has remote address set 109 * to 127.0.0.1 to prevent client from using it to send to remote hosts, 110 * because remote host then will receive 127.0.0.1 as the packet's 111 * source address. 112 */ 113 pj_sockaddr_in remote_addr; 114 115 /** Struct to save incoming socket information. */ 116 incoming_socket_rec accept_data; 117 118 /** When this transport should be closed. */ 119 pj_time_val close_time; 120 121 /** List of callbacks to be called when client attempt to use this 122 * transport while it's not connected (i.e. still connecting). 123 */ 124 pj_list cb_list; 125 }; 126 32 #include <pj/lock.h> 33 34 35 #define THIS_FILE "transport" 127 36 128 37 /* 129 38 * Transport manager. 130 39 */ 131 struct pjsip_t ransport_mgr132 { 133 pj_hash_table_t *t ransport_table;134 pj_ mutex_t *mutex;40 struct pjsip_tpmgr 41 { 42 pj_hash_table_t *table; 43 pj_lock_t *lock; 135 44 pjsip_endpoint *endpt; 136 45 pj_ioqueue_t *ioqueue; 137 pj_time_val next_idle_check; 138 pj_size_t send_buf_size; 139 pj_size_t recv_buf_size; 140 void (*message_callback)(pjsip_endpoint*, pjsip_rx_data *rdata); 46 pj_timer_heap_t *timer_heap; 47 pjsip_tpfactory factory_list; 48 void (*msg_cb)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); 141 49 }; 142 50 143 /* 144 * Transport role. 145 */ 146 typedef enum transport_role_e 147 { 148 TRANSPORT_ROLE_LISTENER, 149 TRANSPORT_ROLE_TRANSPORT, 150 } transport_role_e; 51 52 53 /***************************************************************************** 54 * 55 * GENERAL TRANSPORT (NAMES, TYPES, ETC.) 56 * 57 *****************************************************************************/ 58 59 /* 60 * Transport names. 61 */ 62 const struct 63 { 64 pjsip_transport_type_e type; 65 pj_uint16_t port; 66 pj_str_t name; 67 unsigned flag; 68 } transport_names[] = 69 { 70 { PJSIP_TRANSPORT_UNSPECIFIED, 0, {NULL, 0}, 0}, 71 { PJSIP_TRANSPORT_UDP, 5060, {"UDP", 3}, PJSIP_TRANSPORT_DATAGRAM}, 72 { PJSIP_TRANSPORT_TCP, 5060, {"TCP", 3}, PJSIP_TRANSPORT_RELIABLE}, 73 { PJSIP_TRANSPORT_TLS, 5061, {"TLS", 3}, PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE}, 74 { PJSIP_TRANSPORT_SCTP, 5060, {"SCTP", 4}, PJSIP_TRANSPORT_RELIABLE} 75 }; 76 77 78 /* 79 * Get transport type from name. 80 */ 81 PJ_DEF(pjsip_transport_type_e) 82 pjsip_transport_get_type_from_name(const pj_str_t *name) 83 { 84 unsigned i; 85 86 for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { 87 if (pj_stricmp(name, &transport_names[i].name) == 0) { 88 return transport_names[i].type; 89 } 90 } 91 92 pj_assert(!"Invalid transport name"); 93 return PJSIP_TRANSPORT_UNSPECIFIED; 94 } 95 96 97 /* 98 * Get the transport type for the specified flags. 99 */ 100 PJ_DEF(pjsip_transport_type_e) 101 pjsip_transport_get_type_from_flag(unsigned flag) 102 { 103 unsigned i; 104 105 for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { 106 if (transport_names[i].flag == flag) { 107 return transport_names[i].type; 108 } 109 } 110 111 pj_assert(!"Invalid transport type"); 112 return PJSIP_TRANSPORT_UNSPECIFIED; 113 } 114 115 PJ_DEF(unsigned) 116 pjsip_transport_get_flag_from_type( pjsip_transport_type_e type ) 117 { 118 PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), 0); 119 return transport_names[type].flag; 120 } 121 122 /* 123 * Get the default SIP port number for the specified type. 124 */ 125 PJ_DEF(int) 126 pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type) 127 { 128 PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), 5060); 129 return transport_names[type].port; 130 } 131 132 133 /***************************************************************************** 134 * 135 * TRANSMIT DATA BUFFER MANIPULATION. 136 * 137 *****************************************************************************/ 138 139 /* 140 * Create new transmit buffer. 141 */ 142 PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr, 143 pjsip_tx_data **p_tdata ) 144 { 145 pj_pool_t *pool; 146 pjsip_tx_data *tdata; 147 pj_status_t status; 148 149 PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL); 150 151 PJ_LOG(5, ("", "pjsip_tx_data_create")); 152 153 pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p", 154 PJSIP_POOL_LEN_TDATA, 155 PJSIP_POOL_INC_TDATA ); 156 if (!pool) 157 return PJ_ENOMEM; 158 159 tdata = pj_pool_zalloc(pool, sizeof(pjsip_tx_data)); 160 tdata->pool = pool; 161 tdata->mgr = mgr; 162 pj_snprintf(tdata->obj_name, PJ_MAX_OBJ_NAME, "tdta%p", tdata); 163 164 status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt); 165 if (status != PJ_SUCCESS) { 166 pjsip_endpt_destroy_pool( mgr->endpt, tdata->pool ); 167 return status; 168 } 169 170 //status = pj_lock_create_simple_mutex(pool, "tdta%p", &tdata->lock); 171 status = pj_lock_create_null_mutex(pool, "tdta%p", &tdata->lock); 172 if (status != PJ_SUCCESS) { 173 pjsip_endpt_destroy_pool( mgr->endpt, tdata->pool ); 174 return status; 175 } 176 177 pj_ioqueue_op_key_init(&tdata->op_key, sizeof(tdata->op_key)); 178 179 *p_tdata = tdata; 180 return PJ_SUCCESS; 181 } 182 183 184 /* 185 * Add reference to tx buffer. 186 */ 187 PJ_DEF(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata ) 188 { 189 pj_atomic_inc(tdata->ref_cnt); 190 } 191 192 /* 193 * Decrease transport data reference, destroy it when the reference count 194 * reaches zero. 195 */ 196 PJ_DEF(void) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata ) 197 { 198 pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); 199 if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) { 200 PJ_LOG(5,(tdata->obj_name, "destroying txdata")); 201 pj_atomic_destroy( tdata->ref_cnt ); 202 pj_lock_destroy( tdata->lock ); 203 pjsip_endpt_destroy_pool( tdata->mgr->endpt, tdata->pool ); 204 } 205 } 206 207 /* 208 * Invalidate the content of the print buffer to force the message to be 209 * re-printed when sent. 210 */ 211 PJ_DEF(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata ) 212 { 213 tdata->buf.cur = tdata->buf.start; 214 } 215 216 PJ_DEF(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata ) 217 { 218 return tdata->buf.cur != tdata->buf.start; 219 } 220 221 222 223 /***************************************************************************** 224 * 225 * TRANSPORT KEY 226 * 227 *****************************************************************************/ 151 228 152 229 /* 153 230 * Transport key for indexing in the hash table. 154 * WATCH OUT FOR ALIGNMENT PROBLEM HERE!155 231 */ 156 232 typedef struct transport_key … … 162 238 } transport_key; 163 239 164 /* 165 * Transport callback. 166 */ 167 struct transport_callback 168 { 169 PJ_DECL_LIST_MEMBER(struct transport_callback); 170 171 /** User defined token to be passed to the callback. */ 172 void *token; 173 174 /** The callback function. */ 175 void (*cb)(pjsip_transport_t *tr, void *token, pj_status_t status); 176 177 }; 178 179 /* 180 * Transport names. 181 */ 182 const struct 183 { 184 pjsip_transport_type_e type; 185 pj_uint16_t port; 186 pj_str_t name; 187 } transport_names[] = 188 { 189 { PJSIP_TRANSPORT_UNSPECIFIED, 0, {NULL, 0}}, 190 { PJSIP_TRANSPORT_UDP, 5060, {"UDP", 3}}, 191 #if PJ_HAS_TCP 192 { PJSIP_TRANSPORT_TCP, 5060, {"TCP", 3}}, 193 { PJSIP_TRANSPORT_TLS, 5061, {"TLS", 3}}, 194 { PJSIP_TRANSPORT_SCTP, 5060, {"SCTP", 4}} 195 #endif 196 }; 197 198 static void on_ioqueue_read(pj_ioqueue_key_t *key, 199 pj_ioqueue_op_key_t *op_key, 200 pj_ssize_t bytes_read); 201 static void on_ioqueue_write(pj_ioqueue_key_t *key, 202 pj_ioqueue_op_key_t *op_key, 203 pj_ssize_t bytes_sent); 204 static void on_ioqueue_accept(pj_ioqueue_key_t *key, 205 pj_ioqueue_op_key_t *op_key, 206 pj_sock_t newsock, 207 int status); 208 static void on_ioqueue_connect(pj_ioqueue_key_t *key, 209 int status); 210 211 static pj_ioqueue_callback ioqueue_transport_callback = 212 { 213 &on_ioqueue_read, 214 &on_ioqueue_write, 215 &on_ioqueue_accept, 216 &on_ioqueue_connect 217 }; 218 219 static void init_key_from_transport(transport_key *key, 220 const pjsip_transport_t *tr) 221 { 222 /* This is to detect alignment problems. */ 223 pj_assert(sizeof(transport_key) == 8); 224 225 key->type = (pj_uint8_t)tr->type; 226 key->zero = 0; 227 key->addr = pj_sockaddr_in_get_addr(&tr->remote_addr).s_addr; 228 key->port = pj_sockaddr_in_get_port(&tr->remote_addr); 229 /* 230 if (key->port == 0) { 231 key->port = pj_sockaddr_in_get_port(&tr->local_addr); 232 } 233 */ 234 } 235 236 #if PJ_HAS_TCP 237 static void init_tcp_key(transport_key *key, pjsip_transport_type_e type, 238 const pj_sockaddr_in *addr) 239 { 240 /* This is to detect alignment problems. */ 241 pj_assert(sizeof(transport_key) == 8); 242 243 key->type = (pj_uint8_t)type; 244 key->zero = 0; 245 key->addr = pj_sockaddr_in_get_addr(addr).s_addr; 246 key->port = pj_sockaddr_in_get_port(addr); 247 } 248 #endif 249 250 static void init_udp_key(transport_key *key, pjsip_transport_type_e type, 251 const pj_sockaddr_in *addr) 252 { 253 PJ_UNUSED_ARG(addr); 254 255 /* This is to detect alignment problems. */ 256 pj_assert(sizeof(transport_key) == 8); 257 258 pj_memset(key, 0, sizeof(*key)); 259 key->type = (pj_uint8_t)type; 260 261 #if 0 /* Not sure why we need to make 127.0.0.1 a special case */ 262 if (addr->sin_addr.s_addr == inet_addr("127.0.0.1")) { 263 /* This looks more complicated than it is because key->addr uses 264 * the host version of the address (i.e. converted with ntohl()). 265 */ 266 pj_str_t localaddr = pj_str("127.0.0.1"); 267 pj_sockaddr_in addr; 268 pj_sockaddr_set_str_addr(&addr, &localaddr); 269 key->addr = pj_sockaddr_in_get_addr(&addr); 270 } 271 #endif 272 } 273 274 /* 275 * Get type format name (for pool name). 276 */ 277 static const char *transport_get_name_format( int type ) 278 { 279 switch (type) { 280 case PJSIP_TRANSPORT_UDP: 281 return " udp%p"; 282 #if PJ_HAS_TCP 283 case PJSIP_TRANSPORT_TCP: 284 return " tcp%p"; 285 case PJSIP_TRANSPORT_TLS: 286 return " tls%p"; 287 case PJSIP_TRANSPORT_SCTP: 288 return "sctp%p"; 289 #endif 290 } 291 pj_assert(0); 292 return 0; 293 } 294 295 /* 296 * Get the default SIP port number for the specified type. 297 */ 298 PJ_DEF(int) pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type) 299 { 300 return transport_names[type].port; 301 } 302 303 /* 304 * Get transport name. 305 */ 306 static const char *get_type_name(int type) 307 { 308 return transport_names[type].name.ptr; 309 } 310 311 /* 312 * Get transport type from name. 313 */ 314 PJ_DEF(pjsip_transport_type_e) 315 pjsip_transport_get_type_from_name(const pj_str_t *name) 316 { 317 unsigned i; 318 319 for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { 320 if (pj_stricmp(name, &transport_names[i].name) == 0) { 321 return transport_names[i].type; 322 } 323 } 324 return PJSIP_TRANSPORT_UNSPECIFIED; 325 } 326 327 /* 328 * Create new transmit buffer. 329 */ 330 pj_status_t pjsip_tx_data_create( pjsip_transport_mgr *mgr, 331 pjsip_tx_data **p_tdata ) 332 { 333 pj_pool_t *pool; 334 pjsip_tx_data *tdata; 240 241 /***************************************************************************** 242 * 243 * TRANSPORT 244 * 245 *****************************************************************************/ 246 247 static void transport_send_callback(pjsip_transport *transport, 248 void *token, 249 pj_status_t status) 250 { 251 pjsip_tx_data *tdata = token; 252 253 PJ_UNUSED_ARG(transport); 254 255 /* Mark pending off so that app can resend/reuse txdata from inside 256 * the callback. 257 */ 258 tdata->is_pending = 0; 259 260 /* Call callback, if any. */ 261 if (tdata->cb) { 262 (*tdata->cb)(tdata->token, tdata, status); 263 } 264 265 /* Decrement reference count. */ 266 pjsip_tx_data_dec_ref(tdata); 267 } 268 269 /* 270 * Send a SIP message using the specified transport. 271 */ 272 PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr, 273 pjsip_tx_data *tdata, 274 const pj_sockaddr_in *addr, 275 void *token, 276 void (*cb)(void *token, 277 pjsip_tx_data *tdata, 278 pj_status_t)) 279 { 335 280 pj_status_t status; 336 281 337 PJ_LOG(5, ("", "pjsip_tx_data_create")); 338 339 PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL); 340 341 pool = pjsip_endpt_create_pool( mgr->endpt, "ptdt%p", 342 PJSIP_POOL_LEN_TDATA, 343 PJSIP_POOL_INC_TDATA ); 344 if (!pool) { 345 return PJ_ENOMEM; 346 } 347 tdata = pj_pool_calloc(pool, 1, sizeof(pjsip_tx_data)); 348 tdata->pool = pool; 349 tdata->mgr = mgr; 350 pj_sprintf(tdata->obj_name,"txd%p", tdata); 351 352 status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt); 353 if (status != PJ_SUCCESS) { 354 pjsip_endpt_destroy_pool( mgr->endpt, tdata->pool ); 355 return status; 356 } 357 358 *p_tdata = tdata; 359 return PJ_SUCCESS; 360 } 361 362 /* 363 * Add reference to tx buffer. 364 */ 365 PJ_DEF(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata ) 366 { 367 pj_atomic_inc(tdata->ref_cnt); 368 } 369 370 /* 371 * Decrease transport data reference, destroy it when the reference count 372 * reaches zero. 373 */ 374 PJ_DEF(void) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata ) 375 { 376 pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); 377 if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) { 378 PJ_LOG(6,(tdata->obj_name, "destroying txdata")); 379 pj_atomic_destroy( tdata->ref_cnt ); 380 pjsip_endpt_destroy_pool( tdata->mgr->endpt, tdata->pool ); 381 } 382 } 383 384 /* 385 * Invalidate the content of the print buffer to force the message to be 386 * re-printed when sent. 387 */ 388 PJ_DEF(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata ) 389 { 390 tdata->buf.cur = tdata->buf.start; 391 } 392 393 /* 394 * Get the transport type. 395 */ 396 PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type( const pjsip_transport_t * tr) 397 { 398 return tr->type; 399 } 400 401 /* 402 * Get transport type from transport flag. 403 */ 404 PJ_DEF(pjsip_transport_type_e) pjsip_get_transport_type_from_flag(unsigned flag) 405 { 406 #if PJ_HAS_TCP 407 if (flag & PJSIP_TRANSPORT_SECURE) { 408 return PJSIP_TRANSPORT_TLS; 409 } else if (flag & PJSIP_TRANSPORT_RELIABLE) { 410 return PJSIP_TRANSPORT_TCP; 411 } else 412 #else 413 PJ_UNUSED_ARG(flag); 414 #endif 415 { 416 return PJSIP_TRANSPORT_UDP; 417 } 418 } 419 420 /* 421 * Get the transport type name. 422 */ 423 PJ_DEF(const char *) pjsip_transport_get_type_name( const pjsip_transport_t * tr) 424 { 425 return get_type_name(tr->type); 426 } 427 428 /* 429 * Get the transport's object name. 430 */ 431 PJ_DEF(const char*) pjsip_transport_get_obj_name( const pjsip_transport_t *tr ) 432 { 433 return tr->obj_name; 434 } 435 436 /* 437 * Get the transport's reference counter. 438 */ 439 PJ_DEF(int) pjsip_transport_get_ref_cnt( const pjsip_transport_t *tr ) 440 { 441 return pj_atomic_get(tr->ref_cnt); 442 } 443 444 /* 445 * Get transport local address. 446 */ 447 PJ_DEF(const pj_sockaddr_in*) pjsip_transport_get_local_addr( pjsip_transport_t *tr ) 448 { 449 return &tr->local_addr; 450 } 451 452 /* 453 * Get address name. 454 */ 455 PJ_DEF(const pj_sockaddr_in*) pjsip_transport_get_addr_name (pjsip_transport_t *tr) 456 { 457 return &tr->addr_name; 458 } 459 460 /* 461 * Get transport remote address. 462 */ 463 PJ_DEF(const pj_sockaddr_in*) pjsip_transport_get_remote_addr( const pjsip_transport_t *tr ) 464 { 465 return &tr->remote_addr; 466 } 467 468 /* 469 * Get transport flag. 470 */ 471 PJ_DEF(unsigned) pjsip_transport_get_flag( const pjsip_transport_t * tr ) 472 { 473 return tr->flag; 474 } 475 476 /* 477 * Add reference to the specified transport. 478 */ 479 PJ_DEF(void) pjsip_transport_add_ref( pjsip_transport_t * tr ) 480 { 481 pj_atomic_inc(tr->ref_cnt); 482 } 483 484 /* 485 * Decrease the reference time of the transport. 486 */ 487 PJ_DEF(void) pjsip_transport_dec_ref( pjsip_transport_t *tr ) 488 { 489 pj_assert(tr->ref_cnt > 0); 490 if (pj_atomic_dec_and_get(tr->ref_cnt) == 0) { 491 pj_gettimeofday(&tr->close_time); 492 tr->close_time.sec += PJSIP_TRANSPORT_CLOSE_TIMEOUT; 493 } 494 } 495 496 /* 497 * Open the underlying transport. 498 */ 499 static pj_status_t create_socket( pjsip_transport_type_e type, 500 pj_sockaddr_in *local, 501 pj_sock_t *p_sock) 502 { 503 int sock_family; 504 int sock_type; 505 int sock_proto; 506 int len; 507 pj_status_t status; 508 pj_sock_t sock; 509 510 /* Set socket parameters */ 511 if (type == PJSIP_TRANSPORT_UDP) { 512 sock_family = PJ_AF_INET; 513 sock_type = PJ_SOCK_DGRAM; 514 sock_proto = 0; 515 516 #if PJ_HAS_TCP 517 } else if (type == PJSIP_TRANSPORT_TCP) { 518 sock_family = PJ_AF_INET; 519 sock_type = PJ_SOCK_STREAM; 520 sock_proto = 0; 521 #endif 522 } else { 523 return PJ_EINVAL; 524 } 525 526 /* Create socket. */ 527 status = pj_sock_socket( sock_family, sock_type, sock_proto, &sock); 528 if (status != PJ_SUCCESS) 529 return status; 530 531 /* Bind the socket to the requested address, or if no address is 532 * specified, let the operating system chooses the address. 533 */ 534 if (/*local->sin_addr.s_addr != 0 &&*/ local->sin_port != 0) { 535 /* Bind to the requested address. */ 536 status = pj_sock_bind(sock, local, sizeof(*local)); 537 if (status != PJ_SUCCESS) { 538 pj_sock_close(sock); 539 return status; 540 } 541 } else if (type == PJSIP_TRANSPORT_UDP) { 542 /* Only for UDP sockets: bind to any address so that the operating 543 * system allocates the port for us. For TCP, let the OS implicitly 544 * bind the socket with connect() syscall (if we bind now, then we'll 545 * get 0.0.0.0 as local address). 546 */ 547 pj_memset(local, 0, sizeof(*local)); 548 local->sin_family = PJ_AF_INET; 549 status = pj_sock_bind(sock, local, sizeof(*local)); 550 if (status != PJ_SUCCESS) { 551 pj_sock_close(sock); 552 return status; 553 } 554 555 /* Get the local address. */ 556 len = sizeof(pj_sockaddr_in); 557 status = pj_sock_getsockname(sock, local, &len); 558 if (status != PJ_SUCCESS) { 559 pj_sock_close(sock); 560 return status; 561 } 562 } 563 564 *p_sock = sock; 565 return PJ_SUCCESS; 566 } 567 568 /* 569 * Close the transport. 570 */ 571 static void destroy_socket( pjsip_transport_t * tr) 572 { 573 pj_assert( pj_atomic_get(tr->ref_cnt) == 0); 574 pj_sock_close(tr->sock); 575 tr->sock = -1; 576 } 577 578 /* 579 * Create a new transport object. 580 */ 581 static pj_status_t create_transport( pjsip_transport_mgr *mgr, 582 pjsip_transport_type_e type, 583 pj_sock_t sock_hnd, 584 const pj_sockaddr_in *local_addr, 585 const pj_sockaddr_in *addr_name, 586 pjsip_transport_t **p_transport ) 587 { 588 pj_pool_t *tr_pool=NULL, *rdata_pool=NULL; 589 pjsip_transport_t *tr = NULL; 590 pj_status_t status; 591 592 /* Allocate pool for transport from endpoint. */ 593 tr_pool = pjsip_endpt_create_pool( mgr->endpt, 594 transport_get_name_format(type), 595 PJSIP_POOL_LEN_TRANSPORT, 596 PJSIP_POOL_INC_TRANSPORT ); 597 if (!tr_pool) { 598 status = PJ_ENOMEM; 599 goto on_error; 600 } 601 602 /* Allocate pool for rdata from endpoint. */ 603 rdata_pool = pjsip_endpt_create_pool( mgr->endpt, 604 "prdt%p", 605 PJSIP_POOL_LEN_RDATA, 606 PJSIP_POOL_INC_RDATA ); 607 if (!rdata_pool) { 608 status = PJ_ENOMEM; 609 goto on_error; 610 } 611 612 /* Allocate and initialize the transport. */ 613 tr = pj_pool_calloc(tr_pool, 1, sizeof(*tr)); 614 tr->pool = tr_pool; 615 tr->type = type; 616 tr->mgr = mgr; 617 tr->sock = sock_hnd; 618 pj_memcpy(&tr->local_addr, local_addr, sizeof(pj_sockaddr_in)); 619 pj_list_init(&tr->cb_list); 620 pj_sprintf(tr->obj_name, transport_get_name_format(type), tr); 621 622 if (type != PJSIP_TRANSPORT_UDP) { 623 tr->flag |= PJSIP_TRANSPORT_RELIABLE; 624 } 625 626 /* Address name. */ 627 if (addr_name == NULL) { 628 addr_name = &tr->local_addr; 629 } 630 pj_memcpy(&tr->addr_name, addr_name, sizeof(*addr_name)); 631 632 /* Create atomic */ 633 status = pj_atomic_create(tr_pool, 0, &tr->ref_cnt); 634 if (status != PJ_SUCCESS) 635 goto on_error; 636 637 /* Init rdata in the transport. */ 638 tr->rdata = pj_pool_alloc(rdata_pool, sizeof(*tr->rdata)); 639 tr->rdata->pool = rdata_pool; 640 tr->rdata->len = 0; 641 tr->rdata->transport = tr; 642 643 /* Init transport mutex. */ 644 status = pj_mutex_create_recursive(tr_pool, "mtr%p", &tr->tr_mutex); 645 if (status != PJ_SUCCESS) 646 goto on_error; 647 648 /* Register to I/O Queue */ 649 status = pj_ioqueue_register_sock( tr_pool, mgr->ioqueue, 650 tr->sock, tr, 651 &ioqueue_transport_callback, 652 &tr->key); 653 if (status != PJ_SUCCESS) 654 goto on_error; 655 656 *p_transport = tr; 657 return PJ_SUCCESS; 658 659 on_error: 660 if (tr && tr->tr_mutex) { 661 pj_mutex_destroy(tr->tr_mutex); 662 } 663 if (tr_pool) { 664 pjsip_endpt_destroy_pool(mgr->endpt, tr_pool); 665 } 666 if (rdata_pool) { 667 pjsip_endpt_destroy_pool(mgr->endpt, rdata_pool); 668 } 669 return status; 670 } 671 672 /* 673 * Destroy transport. 674 */ 675 static void destroy_transport( pjsip_transport_mgr *mgr, pjsip_transport_t *tr) 676 { 677 transport_key hash_key; 678 679 /* Remove from I/O queue. */ 680 pj_ioqueue_unregister( tr->key ); 681 682 /* Remove from hash table */ 683 init_key_from_transport(&hash_key, tr); 684 pj_hash_set(NULL, mgr->transport_table, &hash_key, sizeof(hash_key), NULL); 685 686 /* Close transport. */ 687 destroy_socket(tr); 688 689 /* Destroy the transport mutex. */ 690 pj_mutex_destroy(tr->tr_mutex); 691 692 /* Destroy atomic */ 693 pj_atomic_destroy( tr->ref_cnt ); 694 695 /* Release the pool associated with the rdata. */ 696 pjsip_endpt_destroy_pool(mgr->endpt, tr->rdata->pool ); 697 698 /* Release the pool associated with the transport. */ 699 pjsip_endpt_destroy_pool(mgr->endpt, tr->pool ); 700 } 701 702 703 static pj_status_t transport_send_msg( pjsip_transport_t *tr, 704 pjsip_tx_data *tdata, 705 const pj_sockaddr_in *addr, 706 pj_ssize_t *p_sent) 707 { 708 const char *buf = tdata->buf.start; 709 pj_ssize_t size; 710 pj_status_t status; 711 712 /* Can only send if tdata is not being sent! */ 713 if (pj_ioqueue_is_pending(tr->key, &tdata->op_key)) 282 PJ_ASSERT_RETURN(tr && tdata && addr, PJ_EINVAL); 283 284 /* Is it currently being sent? */ 285 if (tdata->is_pending) { 286 pj_assert(!"Invalid operation step!"); 714 287 return PJSIP_EPENDINGTX; 288 } 715 289 716 290 /* Allocate buffer if necessary. */ … … 721 295 } 722 296 723 /* Print the message if it's not printed */ 724 if (tdata->buf.cur <= tdata->buf.start) { 297 /* Do we need to reprint? */ 298 if (!pjsip_tx_data_is_valid(tdata)) { 299 pj_ssize_t size; 300 725 301 size = pjsip_msg_print( tdata->msg, tdata->buf.start, 726 302 tdata->buf.end - tdata->buf.start); … … 733 309 } 734 310 735 /* Send the message. */ 736 buf = tdata->buf.start; 737 size = tdata->buf.cur - tdata->buf.start; 738 739 if (tr->type == PJSIP_TRANSPORT_UDP) { 740 PJ_LOG(4,(tr->obj_name, "sendto %s:%d, %d bytes, data:\n" 741 "----------- begin msg ------------\n" 742 "%s" 743 "------------ end msg -------------", 744 pj_inet_ntoa(addr->sin_addr), 745 pj_sockaddr_in_get_port(addr), 746 size, buf)); 747 748 status = pj_ioqueue_sendto( tr->key, &tdata->op_key, 749 buf, &size, 0, addr, sizeof(*addr)); 750 } 751 #if PJ_HAS_TCP 752 else { 753 PJ_LOG(4,(tr->obj_name, "sending %d bytes, data:\n" 754 "----------- begin msg ------------\n" 755 "%s" 756 "------------ end msg -------------", 757 size, buf)); 758 759 status = pj_ioqueue_send(tr->key, &tdata->op_key, buf, &size, 0); 760 } 761 #else 762 else { 763 pj_assert(!"Unsupported transport"); 764 status = PJSIP_EUNSUPTRANSPORT; 765 } 766 #endif 767 768 *p_sent = size; 311 /* Save callback data. */ 312 tdata->token = token; 313 tdata->cb = cb; 314 315 /* Add reference counter. */ 316 pjsip_tx_data_add_ref(tdata); 317 318 /* Mark as pending. */ 319 tdata->is_pending = 1; 320 321 /* Send to transport. */ 322 status = (*tr->send_msg)(tr, tdata->buf.start, 323 tdata->buf.cur - tdata->buf.start, 324 &tdata->op_key, 325 addr, tdata, &transport_send_callback); 326 327 if (status != PJ_EPENDING) { 328 tdata->is_pending = 0; 329 pjsip_tx_data_dec_ref(tdata); 330 } 331 769 332 return status; 770 333 } 771 334 772 /* 773 * Send a SIP message using the specified transport, to the address specified 774 * in the outgoing data. 775 */ 776 PJ_DEF(pj_status_t) pjsip_transport_send_msg( pjsip_transport_t *tr, 777 pjsip_tx_data *tdata, 778 const pj_sockaddr_in *addr, 779 pj_ssize_t *sent) 780 { 781 PJ_LOG(5, (tr->obj_name, "pjsip_transport_send_msg(tdata=%s)", tdata->obj_name)); 782 783 return transport_send_msg(tr, tdata, addr, sent ); 784 } 785 786 /////////////////////////////////////////////////////////////////////////////// 335 static void transport_idle_callback(pj_timer_heap_t *timer_heap, 336 struct pj_timer_entry *entry) 337 { 338 pjsip_transport *tp = entry->user_data; 339 pj_assert(tp != NULL); 340 341 PJ_UNUSED_ARG(timer_heap); 342 343 entry->id = PJ_FALSE; 344 pjsip_transport_unregister(tp->tpmgr, tp); 345 } 346 347 /* 348 * Add ref. 349 */ 350 PJ_DEF(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp ) 351 { 352 PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL); 353 354 if (pj_atomic_inc_and_get(tp->ref_cnt) == 1) { 355 pj_lock_acquire(tp->tpmgr->lock); 356 /* Verify again. */ 357 if (pj_atomic_get(tp->ref_cnt) == 1) { 358 if (tp->idle_timer.id != PJ_FALSE) { 359 pj_timer_heap_cancel(tp->tpmgr->timer_heap, &tp->idle_timer); 360 tp->idle_timer.id = PJ_FALSE; 361 } 362 } 363 pj_lock_release(tp->tpmgr->lock); 364 } 365 366 return PJ_SUCCESS; 367 } 368 369 /* 370 * Dec ref. 371 */ 372 PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp ) 373 { 374 PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL); 375 376 pj_assert(pj_atomic_get(tp->ref_cnt) > 0); 377 378 if (pj_atomic_dec_and_get(tp->ref_cnt) == 0) { 379 pj_lock_acquire(tp->tpmgr->lock); 380 /* Verify again. */ 381 if (pj_atomic_get(tp->ref_cnt) == 0) { 382 pj_time_val delay = { PJSIP_TRANSPORT_IDLE_TIME, 0 }; 383 384 pj_assert(tp->idle_timer.id == 0); 385 tp->idle_timer.id = PJ_TRUE; 386 pj_timer_heap_schedule(tp->tpmgr->timer_heap, &tp->idle_timer, &delay); 387 } 388 pj_lock_release(tp->tpmgr->lock); 389 } 390 391 return PJ_SUCCESS; 392 } 393 394 395 /** 396 * Register a transport. 397 */ 398 PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr, 399 pjsip_transport *tp ) 400 { 401 transport_key key; 402 403 /* Init. */ 404 tp->tpmgr = mgr; 405 pj_memset(&tp->idle_timer, 0, sizeof(tp->idle_timer)); 406 tp->idle_timer.user_data = tp; 407 tp->idle_timer.cb = &transport_idle_callback; 408 409 /* 410 * Register to hash table. 411 */ 412 key.type = (pj_uint8_t)tp->type; 413 key.zero = 0; 414 key.addr = pj_ntohl(tp->rem_addr.sin_addr.s_addr); 415 key.port = pj_ntohs(tp->rem_addr.sin_port); 416 417 pj_lock_acquire(mgr->lock); 418 pj_hash_set(tp->pool, mgr->table, &key, sizeof(key), tp); 419 pj_lock_release(mgr->lock); 420 421 return PJ_SUCCESS; 422 } 423 424 425 /** 426 * Unregister transport. 427 */ 428 PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 429 pjsip_transport *tp) 430 { 431 transport_key key; 432 433 PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY); 434 435 pj_lock_acquire(tp->lock); 436 pj_lock_acquire(mgr->lock); 437 438 /* 439 * Unregister timer, if any. 440 */ 441 pj_assert(tp->idle_timer.id == PJ_FALSE); 442 if (tp->idle_timer.id != PJ_FALSE) { 443 pj_timer_heap_cancel(mgr->timer_heap, &tp->idle_timer); 444 tp->idle_timer.id = PJ_FALSE; 445 } 446 447 /* 448 * Unregister from hash table. 449 */ 450 key.type = (pj_uint8_t)tp->type; 451 key.zero = 0; 452 key.addr = pj_ntohl(tp->rem_addr.sin_addr.s_addr); 453 key.port = pj_ntohs(tp->rem_addr.sin_port); 454 455 pj_hash_set(tp->pool, mgr->table, &key, sizeof(key), NULL); 456 457 pj_lock_release(mgr->lock); 458 459 /* Destroy. */ 460 return tp->destroy(tp); 461 } 462 463 464 465 /***************************************************************************** 466 * 467 * TRANSPORT FACTORY 468 * 469 *****************************************************************************/ 470 471 472 PJ_DEF(pj_status_t) pjsip_tpmgr_register_tpfactory( pjsip_tpmgr *mgr, 473 pjsip_tpfactory *tpf) 474 { 475 pjsip_tpfactory *p; 476 pj_status_t status; 477 478 pj_lock_acquire(mgr->lock); 479 480 /* Check that no factory with the same type has been registered. */ 481 status = PJ_SUCCESS; 482 for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) { 483 if (p->type == tpf->type) { 484 status = PJSIP_ETYPEEXISTS; 485 break; 486 } 487 if (p == tpf) { 488 status = PJ_EEXISTS; 489 break; 490 } 491 } 492 493 if (status != PJ_SUCCESS) { 494 pj_lock_release(mgr->lock); 495 return status; 496 } 497 498 pj_list_insert_before(&mgr->factory_list, tpf); 499 500 pj_lock_release(mgr->lock); 501 502 return PJ_SUCCESS; 503 } 504 505 506 /** 507 * Unregister factory. 508 */ 509 PJ_DEF(pj_status_t) pjsip_tpmgr_unregister_tpfactory( pjsip_tpmgr *mgr, 510 pjsip_tpfactory *tpf) 511 { 512 pj_lock_acquire(mgr->lock); 513 514 pj_assert(pj_list_find_node(&mgr->factory_list, tpf) == tpf); 515 pj_list_erase(tpf); 516 517 pj_lock_release(mgr->lock); 518 519 return PJ_SUCCESS; 520 } 521 522 523 /***************************************************************************** 524 * 525 * TRANSPORT MANAGER 526 * 527 *****************************************************************************/ 787 528 788 529 /* 789 530 * Create a new transport manager. 790 531 */ 791 PJ_DEF(pj_status_t) pjsip_transport_mgr_create( pj_pool_t *pool, 792 pjsip_endpoint * endpt, 793 void (*cb)(pjsip_endpoint*, 794 pjsip_rx_data *), 795 pjsip_transport_mgr **p_mgr) 796 { 797 pjsip_transport_mgr *mgr; 532 PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 533 pjsip_endpoint *endpt, 534 pj_ioqueue_t *ioqueue, 535 pj_timer_heap_t *timer_heap, 536 void (*cb)(pjsip_endpoint*, 537 pj_status_t, 538 pjsip_rx_data *), 539 pjsip_tpmgr **p_mgr) 540 { 541 pjsip_tpmgr *mgr; 798 542 pj_status_t status; 799 543 800 PJ_LOG(5, (LOG_TRANSPORT_MGR, "pjsip_transport_mgr_create()")); 801 802 mgr = pj_pool_alloc(pool, sizeof(*mgr)); 544 PJ_ASSERT_RETURN(pool && endpt && cb && p_mgr, PJ_EINVAL); 545 546 PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_create()")); 547 548 mgr = pj_pool_zalloc(pool, sizeof(*mgr)); 803 549 mgr->endpt = endpt; 804 mgr->message_callback = cb; 805 mgr->send_buf_size = DEFAULT_SO_SNDBUF; 806 mgr->recv_buf_size = DEFAULT_SO_RCVBUF; 807 808 mgr->transport_table = pj_hash_create(pool, MGR_HASH_TABLE_SIZE); 809 if (!mgr->transport_table) { 550 mgr->msg_cb = cb; 551 mgr->ioqueue = ioqueue; 552 mgr->timer_heap = timer_heap; 553 pj_list_init(&mgr->factory_list); 554 555 mgr->table = pj_hash_create(pool, PJSIP_TPMGR_HTABLE_SIZE); 556 if (!mgr->table) 810 557 return PJ_ENOMEM; 811 } 812 status = pj_ ioqueue_create(pool, PJSIP_MAX_TRANSPORTS, &mgr->ioqueue);813 if (status != PJ_SUCCESS) {558 559 status = pj_lock_create_recursive_mutex(pool, "tmgr%p", &mgr->lock); 560 if (status != PJ_SUCCESS) 814 561 return status; 815 }816 status = pj_mutex_create_recursive(pool, "tmgr%p", &mgr->mutex);817 if (status != PJ_SUCCESS) {818 pj_ioqueue_destroy(mgr->ioqueue);819 return status;820 }821 pj_gettimeofday(&mgr->next_idle_check);822 mgr->next_idle_check.sec += MGR_IDLE_CHECK_INTERVAL;823 562 824 563 *p_mgr = mgr; 825 return status; 826 } 827 828 /* 564 return PJ_SUCCESS; 565 } 566 567 /* 568 * pjsip_tpmgr_destroy() 569 * 829 570 * Destroy transport manager. 830 571 */ 831 PJ_DEF(pj_status_t) pjsip_t ransport_mgr_destroy( pjsip_transport_mgr *mgr )572 PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr ) 832 573 { 833 574 pj_hash_iterator_t itr_val; 834 575 pj_hash_iterator_t *itr; 835 576 836 PJ_LOG(5, ( LOG_TRANSPORT_MGR, "pjsip_transport_mgr_destroy()"));837 838 pj_ mutex_lock(mgr->mutex);839 840 itr = pj sip_transport_first(mgr, &itr_val);577 PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_destroy()")); 578 579 pj_lock_acquire(mgr->lock); 580 581 itr = pj_hash_first(mgr->table, &itr_val); 841 582 while (itr != NULL) { 842 583 pj_hash_iterator_t *next; 843 pjsip_transport _t*transport;584 pjsip_transport *transport; 844 585 845 transport = pj sip_transport_this(mgr, itr);846 847 next = pj sip_transport_next(mgr, itr);586 transport = pj_hash_this(mgr->table, itr); 587 588 next = pj_hash_next(mgr->table, itr); 848 589 849 590 pj_atomic_set(transport->ref_cnt, 0); 850 destroy_transport(mgr, transport);591 pjsip_transport_unregister(mgr, transport); 851 592 852 593 itr = next; … … 854 595 pj_ioqueue_destroy(mgr->ioqueue); 855 596 856 pj_ mutex_unlock(mgr->mutex);597 pj_lock_release(mgr->lock); 857 598 858 599 return PJ_SUCCESS; 859 600 } 860 601 861 /* 862 * Create listener 863 */ 864 static pj_status_t create_listener( pjsip_transport_mgr *mgr, 865 pjsip_transport_type_e type, 866 pj_sock_t sock_hnd, 867 pj_sockaddr_in *local_addr, 868 const pj_sockaddr_in *addr_name) 869 { 870 pjsip_transport_t *tr; 871 struct transport_key *hash_key; 872 const pj_str_t loopback_addr = { "127.0.0.1", 9 }; 873 pj_status_t status; 874 875 if (mgr->send_buf_size != 0) { 876 int opt_val = mgr->send_buf_size; 877 status = pj_sock_setsockopt( sock_hnd, PJ_SOL_SOCKET, 878 PJ_SO_SNDBUF, 879 &opt_val, sizeof(opt_val)); 880 881 if (status != PJ_SUCCESS) { 882 return status; 883 } 884 } 885 886 if (mgr->recv_buf_size != 0) { 887 int opt_val = mgr->recv_buf_size; 888 status = pj_sock_setsockopt( sock_hnd, PJ_SOL_SOCKET, 889 PJ_SO_RCVBUF, 890 &opt_val, sizeof(opt_val)); 891 if (status != PJ_SUCCESS) { 892 return status; 893 } 894 } 895 896 status = create_transport(mgr, type, sock_hnd, local_addr, addr_name, &tr); 897 if (status != PJ_SUCCESS) { 898 pj_sock_close(sock_hnd); 899 return status; 900 } 901 #if PJ_HAS_TCP 902 if (type == PJSIP_TRANSPORT_TCP) { 903 904 status = pj_sock_listen(tr->sock, BACKLOG); 905 if (status != 0) { 906 destroy_transport(mgr, tr); 907 return status; 908 } 909 910 /* Discard immediate connections. */ 911 do { 912 tr->accept_data.addrlen = sizeof(tr->accept_data.local); 913 status = pj_ioqueue_accept(tr->key, &tr->accept_op, 914 &tr->accept_data.sock, 915 &tr->accept_data.local, 916 &tr->accept_data.remote, 917 &tr->accept_data.addrlen); 918 if (status==PJ_SUCCESS) { 919 pj_sock_close(tr->accept_data.sock); 920 } else if (status != PJ_EPENDING) { 921 destroy_transport(mgr, tr); 922 return status; 923 } 924 } while (status==PJ_SUCCESS); 925 926 } else 927 #endif 928 if (type == PJSIP_TRANSPORT_UDP) { 929 pj_ssize_t bytes; 930 931 /* Discard immediate data. */ 932 do { 933 tr->rdata->addr_len = sizeof(tr->rdata->addr); 934 bytes = PJSIP_MAX_PKT_LEN; 935 status = pj_ioqueue_recvfrom( tr->key, &tr->rdata->op_key, 936 tr->rdata->packet, &bytes, 0, 937 &tr->rdata->addr, 938 &tr->rdata->addr_len); 939 if (status == PJ_SUCCESS) { 940 ; 941 } else if (status != PJ_EPENDING) { 942 destroy_transport(mgr, tr); 943 return status; 944 } 945 } while (status == PJ_SUCCESS); 946 } 947 948 pj_atomic_set(tr->ref_cnt, 1); 949 950 /* Listeners normally have no remote address */ 951 pj_memset(&tr->remote_addr, 0, sizeof(tr->remote_addr)); 952 953 /* Set remote address to 127.0.0.1 for UDP socket bound to 127.0.0.1. 954 * See further comments on struct pjsip_transport_t definition. 602 603 /* 604 * pjsip_tpmgr_receive_packet() 605 * 606 * Called by tranports when they receive a new packet. 607 */ 608 PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr, 609 pjsip_rx_data *rdata) 610 { 611 pjsip_transport *tr = rdata->tp_info.transport; 612 pj_str_t s; 613 614 char *current_pkt; 615 pj_size_t remaining_len; 616 pj_size_t total_processed = 0; 617 618 /* Check size. */ 619 pj_assert(rdata->pkt_info.len > 0); 620 if (rdata->pkt_info.len <= 0) 621 return -1; 622 623 current_pkt = rdata->pkt_info.packet; 624 remaining_len = rdata->pkt_info.len; 625 626 /* Must NULL terminate buffer. This is the requirement of the 627 * parser etc. 955 628 */ 956 if (type == PJSIP_TRANSPORT_UDP && 957 local_addr->sin_addr.s_addr == pj_inet_addr(&loopback_addr).s_addr) 958 { 959 pj_str_t localaddr = pj_str("127.0.0.1"); 960 pj_sockaddr_in_set_str_addr( &tr->remote_addr, &localaddr); 961 } 962 hash_key = pj_pool_alloc(tr->pool, sizeof(transport_key)); 963 init_key_from_transport(hash_key, tr); 964 965 pj_mutex_lock(mgr->mutex); 966 pj_hash_set(tr->pool, mgr->transport_table, 967 hash_key, sizeof(transport_key), tr); 968 pj_mutex_unlock(mgr->mutex); 969 970 PJ_LOG(4,(tr->obj_name, "Listening at %s %s:%d", 971 get_type_name(tr->type), 972 pj_inet_ntoa(tr->local_addr.sin_addr), 973 pj_sockaddr_in_get_port(&tr->local_addr))); 974 PJ_LOG(4,(tr->obj_name, "Listener public address is at %s %s:%d", 975 get_type_name(tr->type), 976 pj_inet_ntoa(tr->addr_name.sin_addr), 977 pj_sockaddr_in_get_port(&tr->addr_name))); 978 return PJ_SUCCESS; 979 } 980 981 /* 982 * Create listener. 983 */ 984 PJ_DEF(pj_status_t) pjsip_create_listener( pjsip_transport_mgr *mgr, 985 pjsip_transport_type_e type, 986 pj_sockaddr_in *local_addr, 987 const pj_sockaddr_in *addr_name) 988 { 989 pj_sock_t sock_hnd; 990 pj_status_t status; 991 992 PJ_LOG(5, (LOG_TRANSPORT_MGR, "pjsip_create_listener(type=%d)", type)); 993 994 status = create_socket(type, local_addr, &sock_hnd); 995 if (status != PJ_SUCCESS) { 996 return status; 997 } 998 999 return create_listener(mgr, type, sock_hnd, local_addr, addr_name); 1000 } 1001 1002 /* 1003 * Create UDP listener. 1004 */ 1005 PJ_DEF(pj_status_t) pjsip_create_udp_listener( pjsip_transport_mgr *mgr, 1006 pj_sock_t sock, 1007 const pj_sockaddr_in *addr_name) 1008 { 1009 pj_sockaddr_in local_addr; 1010 pj_status_t status; 1011 int addrlen = sizeof(local_addr); 1012 1013 status = pj_sock_getsockname(sock, (pj_sockaddr_t*)&local_addr, &addrlen); 1014 if (status != PJ_SUCCESS) 1015 return status; 1016 1017 return create_listener(mgr, PJSIP_TRANSPORT_UDP, sock, 1018 &local_addr, addr_name); 1019 } 1020 1021 /* 1022 * Find transport to be used to send message to remote destination. If no 1023 * suitable transport is found, a new one will be created. 1024 */ 1025 PJ_DEF(void) pjsip_transport_get( pjsip_transport_mgr *mgr, 1026 pj_pool_t *pool, 1027 pjsip_transport_type_e type, 1028 const pj_sockaddr_in *remote, 1029 void *token, 1030 pjsip_transport_completion_callback *cb) 1031 { 1032 transport_key search_key, *hash_key; 1033 pjsip_transport_t *tr; 1034 pj_sockaddr_in local; 1035 pj_sock_t sock_hnd; 1036 pj_status_t status; 1037 struct transport_callback *cb_rec; 1038 1039 PJ_LOG(5, (LOG_TRANSPORT_MGR, "pjsip_transport_get()")); 1040 1041 /* Create the callback record. 1042 */ 1043 cb_rec = pj_pool_calloc(pool, 1, sizeof(*cb_rec)); 1044 cb_rec->token = token; 1045 cb_rec->cb = cb; 1046 1047 /* Create key for hash table look-up. 1048 * The key creation is different for TCP and UDP. 1049 */ 1050 #if PJ_HAS_TCP 1051 if (type==PJSIP_TRANSPORT_TCP) { 1052 init_tcp_key(&search_key, type, remote); 1053 } else 1054 #endif 1055 if (type==PJSIP_TRANSPORT_UDP) { 1056 init_udp_key(&search_key, type, remote); 1057 } 1058 1059 /* Start lock the manager. */ 1060 pj_mutex_lock(mgr->mutex); 1061 1062 /* Lookup the transport in the hash table. */ 1063 tr = pj_hash_get(mgr->transport_table, &search_key, sizeof(transport_key)); 1064 1065 if (tr) { 1066 /* Transport found. If the transport is still busy (i.e. connecting 1067 * is in progress), then just register the callback. Otherwise 1068 * report via the callback if callback is specified. 629 current_pkt[remaining_len] = '\0'; 630 631 /* Process all message fragments. */ 632 while (total_processed < remaining_len) { 633 634 pjsip_msg *msg; 635 pj_size_t msg_fragment_size = 0; 636 637 /* Initialize default fragment size. */ 638 msg_fragment_size = remaining_len; 639 640 /* Null terminate packet. */ 641 642 /* Clear and init msg_info in rdata. 643 * Endpoint might inspect the values there when we call the callback 644 * to report some errors. 1069 645 */ 1070 pj_mutex_unlock(mgr->mutex); 1071 pj_mutex_lock(tr->tr_mutex); 1072 1073 if (tr->flag & PJSIP_TRANSPORT_IOQUEUE_BUSY) { 1074 /* Transport is busy. Just register the callback. */ 1075 pj_list_insert_before(&tr->cb_list, cb_rec); 1076 1077 } else { 1078 /* Transport is ready. Call callback now. 1079 */ 1080 (*cb_rec->cb)(tr, cb_rec->token, PJ_SUCCESS); 1081 } 1082 pj_mutex_unlock(tr->tr_mutex); 1083 1084 return; 1085 } 1086 1087 1088 /* Transport not found. Create new one. */ 1089 pj_memset(&local, 0, sizeof(local)); 1090 local.sin_family = PJ_AF_INET; 1091 status = create_socket(type, &local, &sock_hnd); 1092 if (status != PJ_SUCCESS) { 1093 pj_mutex_unlock(mgr->mutex); 1094 (*cb_rec->cb)(NULL, cb_rec->token, status); 1095 return; 1096 } 1097 status = create_transport(mgr, type, sock_hnd, &local, NULL, &tr); 1098 if (status != PJ_SUCCESS) { 1099 pj_mutex_unlock(mgr->mutex); 1100 (*cb_rec->cb)(NULL, cb_rec->token, status); 1101 return; 1102 } 1103 1104 #if PJ_HAS_TCP 1105 if (type == PJSIP_TRANSPORT_TCP) { 1106 pj_memcpy(&tr->remote_addr, remote, sizeof(pj_sockaddr_in)); 1107 status = pj_ioqueue_connect(tr->key, &tr->remote_addr, 1108 sizeof(pj_sockaddr_in)); 1109 pj_assert(status != 0); 1110 if (status != PJ_EPENDING) { 1111 PJ_TODO(HANDLE_IMMEDIATE_CONNECT); 1112 destroy_transport(mgr, tr); 1113 pj_mutex_unlock(mgr->mutex); 1114 (*cb_rec->cb)(NULL, cb_rec->token, status); 1115 return; 1116 } 1117 } else 1118 #endif 1119 if (type == PJSIP_TRANSPORT_UDP) { 1120 pj_ssize_t size; 1121 1122 do { 1123 tr->rdata->addr_len = sizeof(tr->rdata->addr); 1124 size = PJSIP_MAX_PKT_LEN; 1125 status = pj_ioqueue_recvfrom( tr->key, &tr->rdata->op_key, 1126 tr->rdata->packet, &size, 0, 1127 &tr->rdata->addr, 1128 &tr->rdata->addr_len); 1129 if (status == PJ_SUCCESS) 1130 ; 1131 else if (status != PJ_EPENDING) { 1132 destroy_transport(mgr, tr); 1133 pj_mutex_unlock(mgr->mutex); 1134 (*cb_rec->cb)(NULL, cb_rec->token, status); 1135 return; 1136 } 1137 1138 /* Bug here. 1139 * If data is immediately available, although not likely, it will 1140 * be dropped because we don't expect to have data right after 1141 * the socket is created, do we ?! 1142 */ 1143 PJ_TODO(FIXED_BUG_ON_IMMEDIATE_TRANSPORT_DATA); 1144 1145 } while (status == PJ_SUCCESS); 1146 1147 //Bug: cb will never be called! 1148 // Must force status to PJ_SUCCESS; 1149 //status = PJ_IOQUEUE_PENDING; 1150 1151 status = PJ_SUCCESS; 1152 1153 } else { 1154 pj_mutex_unlock(mgr->mutex); 1155 (*cb_rec->cb)(NULL, cb_rec->token, PJSIP_EUNSUPTRANSPORT); 1156 return; 1157 } 1158 1159 pj_assert(status==PJ_EPENDING || status==PJ_SUCCESS); 1160 pj_mutex_lock(tr->tr_mutex); 1161 hash_key = pj_pool_alloc(tr->pool, sizeof(transport_key)); 1162 pj_memcpy(hash_key, &search_key, sizeof(transport_key)); 1163 pj_hash_set(tr->pool, mgr->transport_table, 1164 hash_key, sizeof(transport_key), tr); 1165 if (status == PJ_SUCCESS) { 1166 pj_mutex_unlock(tr->tr_mutex); 1167 pj_mutex_unlock(mgr->mutex); 1168 (*cb_rec->cb)(tr, cb_rec->token, PJ_SUCCESS); 1169 } else { 1170 pj_list_insert_before(&tr->cb_list, cb_rec); 1171 pj_mutex_unlock(tr->tr_mutex); 1172 pj_mutex_unlock(mgr->mutex); 1173 } 1174 1175 } 1176 1177 #if PJ_HAS_TCP 1178 /* 1179 * Handle completion of asynchronous accept() operation. 1180 * This function is called by handle_events() function. 1181 */ 1182 static void handle_new_connection( pjsip_transport_mgr *mgr, 1183 pjsip_transport_t *listener, 1184 pj_status_t status ) 1185 { 1186 pjsip_transport_t *tr; 1187 transport_key *hash_key; 1188 pj_ssize_t size; 1189 1190 pj_assert (listener->type == PJSIP_TRANSPORT_TCP); 1191 1192 if (status != PJ_SUCCESS) { 1193 PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status, 1194 "Error in accept() completion")); 1195 goto on_return; 1196 } 1197 1198 PJ_LOG(4,(listener->obj_name, "incoming tcp connection from %s:%d", 1199 pj_inet_ntoa(listener->accept_data.remote.sin_addr), 1200 pj_sockaddr_in_get_port(&listener->accept_data.remote))); 1201 1202 status = create_transport(mgr, listener->type, 1203 listener->accept_data.sock, 1204 &listener->accept_data.local, 1205 NULL, &tr); 1206 if (status != PJ_SUCCESS) { 1207 PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status, 1208 "Error in creating new incoming TCP")); 1209 goto on_return; 1210 } 1211 1212 /* 1213 tr->rdata->addr_len = sizeof(tr->rdata->addr); 1214 status = pj_ioqueue_recvfrom( mgr->ioqueue, tr->key, 1215 tr->rdata->packet, PJSIP_MAX_PKT_LEN, 1216 &tr->rdata->addr, 1217 &tr->rdata->addr_len); 1218 */ 1219 tr->rdata->addr = listener->accept_data.remote; 1220 tr->rdata->addr_len = listener->accept_data.addrlen; 1221 1222 size = PJSIP_MAX_PKT_LEN; 1223 status = pj_ioqueue_recv(tr->key, &tr->rdata->op_key, 1224 tr->rdata->packet, &size, 0); 1225 if (status != PJ_EPENDING) { 1226 PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status, 1227 "Error in receiving data")); 1228 PJ_TODO(IMMEDIATE_DATA); 1229 destroy_transport(mgr, tr); 1230 goto on_return; 1231 } 1232 1233 pj_memcpy(&tr->remote_addr, &listener->accept_data.remote, 1234 listener->accept_data.addrlen); 1235 hash_key = pj_pool_alloc(tr->pool, sizeof(transport_key)); 1236 init_key_from_transport(hash_key, tr); 1237 1238 pj_mutex_lock(mgr->mutex); 1239 pj_hash_set(tr->pool, mgr->transport_table, hash_key, 1240 sizeof(transport_key), tr); 1241 pj_mutex_unlock(mgr->mutex); 1242 1243 on_return: 1244 /* Re-initiate asynchronous accept() */ 1245 listener->accept_data.addrlen = sizeof(listener->accept_data.local); 1246 status = pj_ioqueue_accept(listener->key, &listener->accept_op, 1247 &listener->accept_data.sock, 1248 &listener->accept_data.local, 1249 &listener->accept_data.remote, 1250 &listener->accept_data.addrlen); 1251 if (status != PJ_EPENDING) { 1252 PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status, 1253 "Error in receiving data")); 1254 PJ_TODO(IMMEDIATE_ACCEPT); 1255 return; 1256 } 1257 } 1258 1259 /* 1260 * Handle completion of asynchronous connect() function. 1261 * This function is called by the handle_events() function. 1262 */ 1263 static void handle_connect_completion( pjsip_transport_mgr *mgr, 1264 pjsip_transport_t *tr, 1265 pj_status_t status ) 1266 { 1267 struct transport_callback new_list; 1268 struct transport_callback *cb_rec; 1269 pj_ssize_t recv_size; 1270 1271 PJ_UNUSED_ARG(mgr); 1272 1273 /* On connect completion, we must call all registered callbacks in 1274 * the transport. 1275 */ 1276 1277 /* Initialize new list. */ 1278 pj_list_init(&new_list); 1279 1280 /* Hold transport's mutex. We don't want other thread to register a 1281 * callback while we're dealing with it. 1282 */ 1283 pj_mutex_lock(tr->tr_mutex); 1284 1285 /* Copy callback list to new list so that we can call the callbacks 1286 * without holding the mutex. 1287 */ 1288 pj_list_merge_last(&new_list, &tr->cb_list); 1289 1290 /* Clear transport's busy flag. */ 1291 tr->flag &= ~PJSIP_TRANSPORT_IOQUEUE_BUSY; 1292 1293 /* If success, update local address. 1294 * Local address is only available after connect() has returned. 1295 */ 1296 if (status == PJ_SUCCESS) { 1297 int addrlen = sizeof(tr->local_addr); 1298 1299 status = pj_sock_getsockname(tr->sock, 1300 (pj_sockaddr_t*)&tr->local_addr, 1301 &addrlen); 1302 if (status == PJ_SUCCESS) { 1303 pj_memcpy(&tr->addr_name, &tr->local_addr, sizeof(tr->addr_name)); 1304 } 1305 } 1306 1307 /* Unlock mutex. */ 1308 pj_mutex_unlock(tr->tr_mutex); 1309 1310 /* Call all registered callbacks. */ 1311 cb_rec = new_list.next; 1312 while (cb_rec != &new_list) { 1313 struct transport_callback *next; 1314 next = cb_rec->next; 1315 (*cb_rec->cb)(tr, cb_rec->token, status); 1316 cb_rec = next; 1317 } 1318 1319 /* Success? */ 1320 if (status != PJ_SUCCESS) { 1321 destroy_transport(mgr, tr); 1322 PJ_TODO(WTF); 1323 return; 1324 } 1325 1326 /* Initiate read operation to socket. */ 1327 recv_size = PJSIP_MAX_PKT_LEN; 1328 status = pj_ioqueue_recv( tr->key, &tr->rdata->op_key, tr->rdata->packet, 1329 &recv_size, 0); 1330 if (status != PJ_EPENDING) { 1331 destroy_transport(mgr, tr); 1332 PJ_TODO(IMMEDIATE_DATA); 1333 return; 1334 } 1335 } 1336 #endif /* PJ_HAS_TCP */ 1337 1338 /* 1339 * Handle incoming data. 1340 * This function is called when the transport manager receives 'notification' 1341 * from the I/O Queue that the receive operation has completed. 1342 * This function will then attempt to parse the message, and hands over the 1343 * message to the endpoint. 1344 */ 1345 static void handle_received_data( pjsip_transport_mgr *mgr, 1346 pjsip_transport_t *tr, 1347 pj_ssize_t size ) 1348 { 1349 pjsip_msg *msg; 1350 pjsip_rx_data *rdata = tr->rdata; 1351 pj_pool_t *rdata_pool; 1352 pjsip_hdr *hdr; 1353 pj_str_t s; 1354 char *src_addr; 1355 int src_port; 1356 pj_size_t msg_fragment_size = 0; 1357 1358 /* Check size. */ 1359 if (size < 1) { 1360 if (tr->type != PJSIP_TRANSPORT_UDP) { 1361 /* zero bytes indicates transport has been closed for TCP. 1362 * But alas, we can't destroy it now since transactions may still 1363 * have reference to it. In that case, just do nothing, the 1364 * transaction will receive error when it tries to send anything. 1365 * But alas!! UAC transactions wont send anything!!. 1366 * So this is a bug! 1367 */ 1368 if (pj_atomic_get(tr->ref_cnt)==0) { 1369 PJ_LOG(4,(tr->obj_name, "connection closed")); 1370 destroy_transport(mgr, tr); 1371 } else { 1372 PJ_TODO(HANDLE_TCP_TRANSPORT_CLOSED); 1373 //PJ_TODO(SIGNAL_TRANSACTIONS_ON_TRANSPORT_CLOSED); 1374 } 1375 return; 1376 } else { 1377 /* On Windows machines, UDP recv() will return zero upon receiving 1378 * ICMP port unreachable message. 1379 */ 1380 PJ_LOG(4,(tr->obj_name, "Ignored zero length UDP packet (port unreachable?)")); 1381 goto on_return; 1382 } 1383 } 1384 1385 /* Save received time. */ 1386 pj_gettimeofday(&rdata->timestamp); 1387 1388 /* Update length. */ 1389 rdata->len += size; 1390 1391 /* Null terminate packet, this is the requirement of the parser. */ 1392 rdata->packet[rdata->len] = '\0'; 1393 1394 /* Get source address and port for logging purpose. */ 1395 src_addr = pj_inet_ntoa(rdata->addr.sin_addr); 1396 src_port = pj_sockaddr_in_get_port(&rdata->addr); 1397 1398 /* Print the whole data to the log. */ 1399 PJ_LOG(4,(tr->obj_name, "%d bytes recvfrom %s:%d:\n" 1400 "----------- begin msg ------------\n" 1401 "%s" 1402 "------------ end msg -------------", 1403 rdata->len, src_addr, src_port, rdata->packet)); 1404 1405 1406 /* Process all message fragments. */ 1407 while (rdata->len > 0) { 1408 1409 msg_fragment_size = rdata->len; 1410 #if PJ_HAS_TCP 646 pj_memset(&rdata->msg_info, 0, sizeof(rdata->msg_info)); 647 pj_list_init(&rdata->msg_info.parse_err); 648 rdata->msg_info.msg_buf = current_pkt; 649 rdata->msg_info.len = remaining_len; 650 1411 651 /* For TCP transport, check if the whole message has been received. */ 1412 if ( tr->type != PJSIP_TRANSPORT_UDP) {652 if ((tr->flag & PJSIP_TRANSPORT_DATAGRAM) == 0) { 1413 653 pj_status_t msg_status; 1414 msg_status = pjsip_find_msg( rdata->packet, rdata->len, PJ_FALSE,654 msg_status = pjsip_find_msg(current_pkt, remaining_len, PJ_FALSE, 1415 655 &msg_fragment_size); 1416 656 if (msg_status != PJ_SUCCESS) { 1417 if (rdata->len == PJSIP_MAX_PKT_LEN) { 1418 PJSIP_ENDPT_LOG_ERROR((mgr->endpt, tr->obj_name, 1419 PJSIP_EOVERFLOW, 1420 "Buffer discarded for %s:%d", 1421 src_addr, src_port)); 1422 goto on_return; 657 if (remaining_len == PJSIP_MAX_PKT_LEN) { 658 mgr->msg_cb(mgr->endpt, PJSIP_EOVERFLOW, rdata); 659 /* Exhaust all data. */ 660 return rdata->pkt_info.len; 1423 661 } else { 1424 goto tcp_read_packet; 662 /* Not enough data in packet. */ 663 return total_processed; 1425 664 } 1426 665 } 1427 666 } 1428 #endif 1429 1430 /* Clear parser error report */ 1431 pj_list_init(&rdata->parse_err); 667 668 /* Update msg_info. */ 669 rdata->msg_info.len = msg_fragment_size; 1432 670 1433 671 /* Parse the message. */ 1434 PJ_LOG(5,(tr->obj_name, "Parsing %d bytes from %s:%d", msg_fragment_size, 1435 src_addr, src_port)); 1436 1437 msg = pjsip_parse_rdata( rdata->packet, msg_fragment_size, rdata); 672 rdata->msg_info.msg = msg = 673 pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata); 1438 674 if (msg == NULL) { 1439 PJ_LOG(3,(tr->obj_name, "Bad message (%d bytes from %s:%d)", msg_fragment_size, 1440 src_addr, src_port)); 675 mgr->msg_cb(mgr->endpt, PJSIP_EINVALIDMSG, rdata); 1441 676 goto finish_process_fragment; 1442 677 } 1443 678 1444 679 /* Perform basic header checking. */ 1445 if (rdata->call_id.ptr == NULL || rdata->from == NULL || 1446 rdata->to == NULL || rdata->via == NULL || rdata->cseq == NULL) 680 if (rdata->msg_info.call_id.ptr == NULL || 681 rdata->msg_info.from == NULL || 682 rdata->msg_info.to == NULL || 683 rdata->msg_info.via == NULL || 684 rdata->msg_info.cseq == NULL) 1447 685 { 1448 PJ_LOG(3,(tr->obj_name, "Bad message from %s:%d: missing some header", 1449 src_addr, src_port)); 686 mgr->msg_cb(mgr->endpt, PJSIP_EMISSINGHDR, rdata); 1450 687 goto finish_process_fragment; 1451 688 } 1452 689 1453 /* If message is received from address that's different from thesent-by,690 /* If message is received from address that's different from sent-by, 1454 691 * MUST add received parameter to the via. 1455 * In our case, we add Via receive param for EVERY received message,1456 * because it saves us from resolving the host HERE in case sent-by is in1457 * FQDN format. And it doesn't hurt either.1458 692 */ 1459 s = pj_str(src_addr); 1460 pj_strdup(rdata->pool, &rdata->via->recvd_param, &s); 693 s = pj_str(pj_inet_ntoa(rdata->pkt_info.addr.sin_addr)); 694 if (pj_strcmp(&s, &rdata->msg_info.via->sent_by.host) != 0) { 695 pj_strdup(rdata->tp_info.pool, 696 &rdata->msg_info.via->recvd_param, &s); 697 } 1461 698 1462 699 /* RFC 3581: 1463 700 * If message contains "rport" param, put the received port there. 1464 701 */ 1465 if (rdata->via->rport_param == 0) { 1466 rdata->via->rport_param = pj_sockaddr_in_get_port(&rdata->addr); 702 if (rdata->msg_info.via->rport_param == 0) { 703 rdata->msg_info.via->rport_param = 704 pj_ntohs(rdata->pkt_info.addr.sin_port); 1467 705 } 1468 706 … … 1470 708 */ 1471 709 if (msg->type == PJSIP_RESPONSE_MSG) { 1472 hdr = (pjsip_hdr*)rdata->via->next; 1473 if (hdr != &rdata->msg->hdr) { 710 pjsip_hdr *hdr; 711 hdr = (pjsip_hdr*)rdata->msg_info.via->next; 712 if (hdr != &msg->hdr) { 1474 713 hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr); 1475 714 if (hdr) { 1476 PJ_LOG(3,(tr->obj_name, "Bad message from %s:%d: " 1477 "multiple Via in response message", 1478 src_addr, src_port)); 715 mgr->msg_cb(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata); 1479 716 goto finish_process_fragment; 1480 717 } … … 1483 720 1484 721 /* Call the transport manager's upstream message callback. 1485 */ 1486 (*mgr->message_callback)(mgr->endpt, rdata); 722 */ 723 mgr->msg_cb(mgr->endpt, PJ_SUCCESS, rdata); 724 1487 725 1488 726 finish_process_fragment: 1489 rdata->len -= msg_fragment_size; 1490 if (rdata->len > 0) { 1491 pj_memmove(rdata->packet, rdata->packet+msg_fragment_size, rdata->len); 1492 PJ_LOG(4,(tr->obj_name, "Processing next fragment, size=%d bytes", rdata->len)); 1493 } 1494 1495 } /* while (rdata->len > 0) */ 1496 1497 on_return: 1498 /* Reset the pool and rdata */ 1499 rdata_pool = rdata->pool; 1500 pj_pool_reset(rdata_pool); 1501 rdata = pj_pool_alloc( rdata_pool, sizeof(*rdata) ); 1502 rdata->len = 0; 1503 rdata->transport = tr; 1504 rdata->pool = rdata_pool; 1505 tr->rdata = rdata; 1506 1507 /* Read the next packet. */ 1508 rdata->addr_len = sizeof(rdata->addr); 1509 if (tr->type == PJSIP_TRANSPORT_UDP) { 1510 pj_ssize_t size = PJSIP_MAX_PKT_LEN; 1511 pj_ioqueue_recvfrom(tr->key, &tr->rdata->op_key, 1512 tr->rdata->packet, &size, 0, 1513 &rdata->addr, &rdata->addr_len); 1514 PJ_TODO(HANDLE_IMMEDIATE_DATA); 1515 } 1516 1517 #if PJ_HAS_TCP 1518 /* The next 'if' should have been 'else if', but we need to put the 1519 label inside the '#if PJ_HAS_TCP' block to avoid 'unreferenced label' warning. 727 total_processed += msg_fragment_size; 728 current_pkt += msg_fragment_size; 729 remaining_len -= msg_fragment_size; 730 731 } /* while (rdata->pkt_info.len > 0) */ 732 733 734 return total_processed; 735 } 736 737 738 /* 739 * pjsip_tpmgr_alloc_transport() 740 * 741 * Get transport suitable to communicate to remote. Create a new one 742 * if necessary. 743 */ 744 PJ_DEF(pj_status_t) pjsip_tpmgr_alloc_transport( pjsip_tpmgr *mgr, 745 pjsip_transport_type_e type, 746 const pj_sockaddr_in *remote, 747 pjsip_transport **p_transport) 748 { 749 transport_key key; 750 pjsip_transport *transport; 751 pjsip_tpfactory *factory; 752 pj_status_t status; 753 754 pj_lock_acquire(mgr->lock); 755 756 /* First try to get exact destination. */ 757 key.type = (pj_uint8_t)type; 758 key.zero = 0; 759 key.addr = pj_ntohl(remote->sin_addr.s_addr); 760 key.port = pj_ntohs(remote->sin_port); 761 762 transport = pj_hash_get(mgr->table, &key, sizeof(key)); 763 if (transport != NULL) { 764 unsigned flag = pjsip_transport_get_flag_from_type(type); 765 766 /* For datagram transports, try lookup with zero address. */ 767 if (flag & PJSIP_TRANSPORT_DATAGRAM) { 768 key.addr = 0; 769 key.port = 0; 770 771 transport = pj_hash_get(mgr->table, &key, sizeof(key)); 772 } 773 } 774 775 if (transport != NULL) { 776 /* 777 * Transport found! 778 */ 779 pjsip_transport_add_ref(transport); 780 pj_lock_release(mgr->lock); 781 *p_transport = transport; 782 return PJ_SUCCESS; 783 } 784 785 /* 786 * Transport not found! 787 * Find factory that can create such transport. 1520 788 */ 1521 tcp_read_packet: 1522 if (tr->type == PJSIP_TRANSPORT_TCP) { 1523 pj_ssize_t size = PJSIP_MAX_PKT_LEN - tr->rdata->len; 1524 pj_ioqueue_recv( tr->key, &tr->rdata->op_key, 1525 tr->rdata->packet + tr->rdata->len, 1526 &size, 0); 1527 PJ_TODO(HANDLE_IMMEDIATE_DATA_1); 1528 } 1529 #endif 1530 } 1531 1532 static void transport_mgr_on_idle( pjsip_transport_mgr *mgr ) 1533 { 1534 pj_time_val now; 789 factory = mgr->factory_list.next; 790 while (factory != &mgr->factory_list) { 791 if (factory->type == type) 792 break; 793 factory = factory->next; 794 } 795 796 if (factory == &mgr->factory_list) { 797 /* No factory can create the transport! */ 798 pj_lock_release(mgr->lock); 799 return PJSIP_EUNSUPTRANSPORT; 800 } 801 802 /* Request factory to create transport. */ 803 status = factory->create_transport(factory, mgr, mgr->endpt, 804 mgr->ioqueue, remote, p_transport); 805 806 pj_lock_release(mgr->lock); 807 return status; 808 } 809 810 /** 811 * Dump transport info. 812 */ 813 PJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr) 814 { 815 #if PJ_LOG_MAX_LEVEL >= 3 1535 816 pj_hash_iterator_t itr_val; 1536 817 pj_hash_iterator_t *itr; 1537 818 1538 1539 /* Get time for comparing transport's close time. */ 1540 pj_gettimeofday(&now); 1541 if (now.sec < mgr->next_idle_check.sec) { 1542 return; 1543 } 1544 1545 /* Acquire transport manager's lock. */ 1546 pj_mutex_lock(mgr->mutex); 1547 1548 /* Update next idle check. */ 1549 mgr->next_idle_check.sec += MGR_IDLE_CHECK_INTERVAL; 1550 1551 /* Iterate all transports, and close transports that are not used for 1552 some periods. 1553 */ 1554 itr = pjsip_transport_first(mgr, &itr_val); 1555 while (itr != NULL) { 1556 pj_hash_iterator_t *next; 1557 pjsip_transport_t *transport; 1558 1559 transport = pjsip_transport_this(mgr, itr); 1560 1561 next = pjsip_transport_next(mgr, itr); 1562 1563 if (pj_atomic_get(transport->ref_cnt)==0 && 1564 PJ_TIME_VAL_LTE(transport->close_time, now)) 1565 { 1566 destroy_transport(mgr, transport); 1567 } 1568 1569 itr = next; 1570 } 1571 1572 /* Release transport manager's lock. */ 1573 pj_mutex_unlock(mgr->mutex); 1574 } 1575 1576 static void on_ioqueue_read(pj_ioqueue_key_t *key, 1577 pj_ioqueue_op_key_t *op_key, 1578 pj_ssize_t bytes_read) 1579 { 1580 pjsip_transport_t *t; 1581 t = pj_ioqueue_get_user_data(key); 1582 1583 handle_received_data( t->mgr, t, bytes_read ); 1584 } 1585 1586 static void on_ioqueue_write(pj_ioqueue_key_t *key, 1587 pj_ioqueue_op_key_t *op_key, 1588 pj_ssize_t bytes_sent) 1589 { 1590 PJ_UNUSED_ARG(key); 1591 PJ_UNUSED_ARG(bytes_sent); 1592 1593 /* Completion of write operation. 1594 * Do nothing. 1595 */ 1596 } 1597 1598 static void on_ioqueue_accept(pj_ioqueue_key_t *key, 1599 pj_ioqueue_op_key_t *op_key, 1600 pj_sock_t newsock, 1601 int status) 1602 { 1603 #if PJ_HAS_TCP 1604 pjsip_transport_t *t; 1605 t = pj_ioqueue_get_user_data(key); 1606 1607 handle_new_connection( t->mgr, t, status ); 1608 #else 1609 PJ_UNUSED_ARG(key); 1610 PJ_UNUSED_ARG(status); 819 pj_lock_acquire(mgr->lock); 820 821 itr = pj_hash_first(mgr->table, &itr_val); 822 if (itr) { 823 PJ_LOG(3, (THIS_FILE, " Dumping transports:")); 824 825 do { 826 char src_addr[128], dst_addr[128]; 827 int src_port, dst_port; 828 pjsip_transport *t; 829 830 t = pj_hash_this(mgr->table, itr); 831 pj_native_strcpy(src_addr, pj_inet_ntoa(t->local_addr.sin_addr)); 832 src_port = pj_ntohs(t->local_addr.sin_port); 833 834 pj_native_strcpy(dst_addr, pj_inet_ntoa(t->rem_addr.sin_addr)); 835 dst_port = pj_ntohs(t->rem_addr.sin_port); 836 837 PJ_LOG(3, (THIS_FILE, " %s %s %s:%d --> %s:%d (refcnt=%d)", 838 t->type_name, 839 t->obj_name, 840 src_addr, src_port, 841 dst_addr, dst_port, 842 pj_atomic_get(t->ref_cnt))); 843 844 itr = pj_hash_next(mgr->table, itr); 845 } while (itr); 846 } 847 848 pj_lock_release(mgr->lock); 1611 849 #endif 1612 850 } 1613 851 1614 static void on_ioqueue_connect(pj_ioqueue_key_t *key, int status)1615 {1616 #if PJ_HAS_TCP1617 pjsip_transport_t *t;1618 t = pj_ioqueue_get_user_data(key);1619 1620 handle_connect_completion( t->mgr, t, status);1621 #else1622 PJ_UNUSED_ARG(key);1623 PJ_UNUSED_ARG(status);1624 #endif1625 }1626 1627 1628 /*1629 * Poll for events.1630 */1631 PJ_DEF(int) pjsip_transport_mgr_handle_events( pjsip_transport_mgr *mgr,1632 const pj_time_val *req_timeout )1633 {1634 int event_count;1635 int break_loop;1636 int result;1637 pj_time_val timeout;1638 1639 PJ_LOG(5, (LOG_TRANSPORT_MGR, "pjsip_transport_mgr_handle_events()"));1640 1641 event_count = 0;1642 break_loop = 0;1643 timeout = *req_timeout;1644 do {1645 result = pj_ioqueue_poll( mgr->ioqueue, &timeout);1646 if (result == 1) {1647 ++event_count;1648 1649 /* Break the loop. */1650 //if (timeout.msec==0 && timeout.sec==0) {1651 break_loop = 1;1652 //}1653 1654 } else {1655 /* On idle, cleanup transport. */1656 transport_mgr_on_idle(mgr);1657 1658 break_loop = 1;1659 }1660 timeout.sec = timeout.msec = 0;1661 } while (!break_loop);1662 1663 return event_count;1664 }1665 1666 1667 PJ_DEF(pj_hash_iterator_t*) pjsip_transport_first( pjsip_transport_mgr *mgr,1668 pj_hash_iterator_t *it )1669 {1670 return pj_hash_first(mgr->transport_table, it);1671 }1672 1673 PJ_DEF(pj_hash_iterator_t*) pjsip_transport_next( pjsip_transport_mgr *mgr,1674 pj_hash_iterator_t *itr )1675 {1676 return pj_hash_next(mgr->transport_table, itr);1677 }1678 1679 PJ_DEF(pjsip_transport_t*) pjsip_transport_this( pjsip_transport_mgr *mgr,1680 pj_hash_iterator_t *itr )1681 {1682 return pj_hash_this(mgr->transport_table, itr);1683 }
Note: See TracChangeset
for help on using the changeset viewer.