Changeset 742 for pjproject/trunk
- Timestamp:
- Sep 26, 2006 1:21:02 PM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
r737 r742 91 91 { 92 92 puts ("Usage:"); 93 puts (" pjsua [options] ");93 puts (" pjsua [options] [SIP URL to call]"); 94 94 puts (""); 95 95 puts ("General options:"); … … 123 123 puts (" TCP and UDP transports on the specified port, unless"); 124 124 puts (" if TCP or UDP is disabled."); 125 puts (" --ip-addr=IP Use the specifed address as SIP and RTP addresses."); 126 puts (" (Hint: the IP may be the public IP of the NAT/router)"); 125 127 puts (" --no-tcp Disable TCP transport."); 126 128 puts (" --no-udp Disable UDP transport."); … … 159 161 160 162 puts (""); 163 puts ("When URL is specified, pjsua will immediately initiate call to that URL"); 164 puts (""); 165 161 166 fflush(stdout); 162 167 } … … 269 274 enum { OPT_CONFIG_FILE, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL, 270 275 OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO, 271 OPT_LOCAL_PORT, OPT_ PROXY, OPT_OUTBOUND_PROXY, OPT_REGISTRAR,272 OPT_REG _TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT,276 OPT_LOCAL_PORT, OPT_IP_ADDR, OPT_PROXY, OPT_OUTBOUND_PROXY, 277 OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT, 273 278 OPT_REALM, OPT_USERNAME, OPT_PASSWORD, 274 279 OPT_USE_STUN1, OPT_USE_STUN2, … … 292 297 { "null-audio", 0, 0, OPT_NULL_AUDIO}, 293 298 { "local-port", 1, 0, OPT_LOCAL_PORT}, 299 { "ip-addr", 1, 0, OPT_IP_ADDR}, 294 300 { "no-tcp", 0, 0, OPT_NO_TCP}, 295 301 { "no-udp", 0, 0, OPT_NO_UDP}, … … 434 440 break; 435 441 442 case OPT_IP_ADDR: /* ip-addr */ 443 cfg->udp_cfg.public_addr = pj_str(pj_optarg); 444 cfg->rtp_cfg.public_addr = pj_str(pj_optarg); 445 break; 446 436 447 case OPT_NO_UDP: /* no-udp */ 437 448 if (cfg->no_tcp) { … … 917 928 pj_ansi_sprintf(line, "--local-port %d\n", config->udp_cfg.port); 918 929 pj_strcat2(&cfg, line); 930 931 /* IP address, if any. */ 932 if (config->udp_cfg.public_addr.slen) { 933 pj_ansi_sprintf(line, "--ip-addr %.*s\n", 934 (int)config->udp_cfg.public_addr.slen, 935 config->udp_cfg.public_addr.ptr); 936 pj_strcat2(&cfg, line); 937 } 919 938 920 939 -
pjproject/trunk/pjsip/include/pjsip/sip_transport.h
r736 r742 727 727 PJ_DECL_LIST_MEMBER(struct pjsip_tpfactory); 728 728 729 char obj_name[PJ_MAX_OBJ_NAME]; /**< Name. */ 730 729 731 pj_pool_t *pool; /**< Owned memory pool. */ 730 732 pj_lock_t *lock; /**< Lock object. */ -
pjproject/trunk/pjsip/include/pjsip/sip_transport_tcp.h
r563 r742 79 79 80 80 81 82 /** 83 * A newer variant of #pjsip_tcp_transport_start(), which allows specifying 84 * the published/public address of the TCP transport. 85 * 86 * @param endpt The SIP endpoint. 87 * @param local Optional local address to bind, or specify the 88 * address to bind the server socket to. Both IP 89 * interface address and port fields are optional. 90 * If IP interface address is not specified, socket 91 * will be bound to PJ_INADDR_ANY. If port is not 92 * specified, socket will be bound to any port 93 * selected by the operating system. 94 * @param a_name Optional published address, which is the address to be 95 * advertised as the address of this SIP transport. 96 * If this argument is NULL, then the bound address 97 * will be used as the published address. 98 * @param async_cnt Number of simultaneous asynchronous accept() 99 * operations to be supported. It is recommended that 100 * the number here corresponds to the number of 101 * processors in the system (or the number of SIP 102 * worker threads). 103 * @param p_factory Optional pointer to receive the instance of the 104 * SIP TCP transport factory just created. 105 * 106 * @return PJ_SUCCESS when the transport has been successfully 107 * started and registered to transport manager, or 108 * the appropriate error code. 109 */ 110 PJ_DECL(pj_status_t) pjsip_tcp_transport_start2(pjsip_endpoint *endpt, 111 const pj_sockaddr_in *local, 112 const pjsip_host_port *a_name, 113 unsigned async_cnt, 114 pjsip_tpfactory **p_factory); 115 116 117 81 118 PJ_END_DECL 82 119 -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r738 r742 725 725 726 726 /** 727 * Transport configuration for creating UDPtransports for both SIP727 * Transport configuration for creating transports for both SIP 728 728 * and media. 729 729 */ … … 739 739 740 740 /** 741 * Optional address where the socket should be bound. 742 */ 743 pj_in_addr ip_addr; 741 * Optional address to advertise as the address of this transport. 742 * Application can specify any address or hostname for this field, 743 * for example it can point to one of the interface address in the 744 * system, or it can point to the public address of a NAT router 745 * where port mappings have been configured for the application. 746 * 747 * Note: this option can be used for both UDP and TCP as well! 748 */ 749 pj_str_t public_addr; 750 751 /** 752 * Optional address where the socket should be bound to. This option 753 * SHOULD only be used to selectively bind the socket to particular 754 * interface (instead of 0.0.0.0), and SHOULD NOT be used to set the 755 * published address of a transport (the public_addr field should be 756 * used for that purpose). 757 * 758 * Note that unlike public_addr field, the address (or hostname) here 759 * MUST correspond to the actual interface address in the host, since 760 * this address will be specified as bind() argument. 761 */ 762 pj_str_t bound_addr; 744 763 745 764 /** -
pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c
r721 r742 70 70 { 71 71 pjsip_tpfactory factory; 72 char obj_name[PJ_MAX_OBJ_NAME];73 72 pj_bool_t is_registered; 74 73 pjsip_endpoint *endpt; … … 185 184 * TCP listener. 186 185 */ 187 PJ_DEF(pj_status_t) pjsip_tcp_transport_start (pjsip_endpoint *endpt,186 PJ_DEF(pj_status_t) pjsip_tcp_transport_start2(pjsip_endpoint *endpt, 188 187 const pj_sockaddr_in *local, 188 const pjsip_host_port *a_name, 189 189 unsigned async_cnt, 190 190 pjsip_tpfactory **p_factory) … … 201 201 PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL); 202 202 203 /* Verify that address given in a_name (if any) is valid */ 204 if (a_name && a_name->host.slen) { 205 pj_sockaddr_in tmp; 206 207 status = pj_sockaddr_in_init(&tmp, &a_name->host, 208 (pj_uint16_t)a_name->port); 209 if (status != PJ_SUCCESS || tmp.sin_addr.s_addr == PJ_INADDR_ANY || 210 tmp.sin_addr.s_addr == PJ_INADDR_NONE) 211 { 212 /* Invalid address */ 213 return PJ_EINVAL; 214 } 215 } 203 216 204 217 pool = pjsip_endpt_create_pool(endpt, "tcplis", POOL_LIS_INIT, … … 215 228 listener->sock = PJ_INVALID_SOCKET; 216 229 217 pj_ansi_strcpy(listener-> obj_name, "tcp");230 pj_ansi_strcpy(listener->factory.obj_name, "tcplis"); 218 231 219 232 status = pj_lock_create_recursive_mutex(pool, "tcplis", … … 246 259 goto on_error; 247 260 248 /* If the address returns 0.0.0.0, use the first interface address249 * as the transport'saddress.261 /* If published host/IP is specified, then use that address as the 262 * listener advertised address. 250 263 */ 251 if (listener_addr->sin_addr.s_addr == 0) { 252 pj_in_addr hostip; 253 254 status = pj_gethostip(&hostip); 255 if (status != PJ_SUCCESS) 256 goto on_error; 257 258 listener_addr->sin_addr = hostip; 259 } 260 261 pj_ansi_snprintf(listener->obj_name, sizeof(listener->obj_name), 262 "tcp:%d", (int)pj_ntohs(listener_addr->sin_port)); 263 264 /* Save the address name */ 265 sockaddr_to_host_port(listener->factory.pool, 266 &listener->factory.addr_name, listener_addr); 264 if (a_name && a_name->host.slen) { 265 /* Copy the address */ 266 listener->factory.addr_name = *a_name; 267 pj_strdup(listener->factory.pool, &listener->factory.addr_name.host, 268 &a_name->host); 269 listener->factory.addr_name.port = a_name->port; 270 271 } else { 272 /* No published address is given, use the bound address */ 273 274 /* If the address returns 0.0.0.0, use the default 275 * interface address as the transport's address. 276 */ 277 if (listener_addr->sin_addr.s_addr == 0) { 278 pj_in_addr hostip; 279 280 status = pj_gethostip(&hostip); 281 if (status != PJ_SUCCESS) 282 goto on_error; 283 284 listener_addr->sin_addr = hostip; 285 } 286 287 /* Save the address name */ 288 sockaddr_to_host_port(listener->factory.pool, 289 &listener->factory.addr_name, listener_addr); 290 } 291 292 /* If port is zero, get the bound port */ 293 if (listener->factory.addr_name.port == 0) { 294 listener->factory.addr_name.port = pj_ntohs(listener_addr->sin_port); 295 } 296 297 pj_ansi_snprintf(listener->factory.obj_name, 298 sizeof(listener->factory.obj_name), 299 "tcplis:%d", listener->factory.addr_name.port); 300 267 301 268 302 /* Start listening to the address */ … … 320 354 } 321 355 322 PJ_LOG(4,(listener->obj_name, 323 "SIP TCP listener ready for incoming connections at %s:%d", 324 pj_inet_ntoa(listener_addr->sin_addr), 325 (int)pj_ntohs(listener_addr->sin_port))); 356 PJ_LOG(4,(listener->factory.obj_name, 357 "SIP TCP listener ready for incoming connections at %.*s:%d", 358 (int)listener->factory.addr_name.host.slen, 359 listener->factory.addr_name.host.ptr, 360 listener->factory.addr_name.port)); 326 361 327 362 /* Return the pointer to user */ … … 333 368 lis_destroy(&listener->factory); 334 369 return status; 370 } 371 372 373 /* 374 * This is the public API to create, initialize, register, and start the 375 * TCP listener. 376 */ 377 PJ_DEF(pj_status_t) pjsip_tcp_transport_start( pjsip_endpoint *endpt, 378 const pj_sockaddr_in *local, 379 unsigned async_cnt, 380 pjsip_tpfactory **p_factory) 381 { 382 return pjsip_tcp_transport_start2(endpt, local, NULL, async_cnt, p_factory); 335 383 } 336 384 … … 374 422 pj_pool_t *pool = listener->factory.pool; 375 423 376 PJ_LOG(4,(listener-> obj_name, "SIP TCP listener destroyed"));424 PJ_LOG(4,(listener->factory.obj_name, "SIP TCP listener destroyed")); 377 425 378 426 listener->factory.pool = NULL; … … 856 904 * Error in accept(). 857 905 */ 858 tcp_perror(listener->obj_name, "Error in accept()", status); 906 tcp_perror(listener->factory.obj_name, "Error in accept()", 907 status); 859 908 860 909 /* … … 866 915 ++err_cnt; 867 916 if (err_cnt >= 10) { 868 PJ_LOG(1, (listener-> obj_name,917 PJ_LOG(1, (listener->factory.obj_name, 869 918 "Too many errors, listener stopping")); 870 919 } … … 883 932 } 884 933 885 PJ_LOG(4,(listener-> obj_name,934 PJ_LOG(4,(listener->factory.obj_name, 886 935 "TCP listener %.*s:%d: got incoming TCP connection " 887 936 "from %s:%d, sock=%d", -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r721 r742 799 799 */ 800 800 if (stun.stun_srv1.slen) { 801 /* 802 * STUN is specified, resolve the address with STUN. 803 */ 801 804 status = pj_stun_get_mapped_addr(&pjsua_var.cp.factory, 1, &sock, 802 805 &stun.stun_srv1, … … 811 814 } 812 815 816 } else if (p_pub_addr->sin_addr.s_addr != 0) { 817 /* 818 * Public address is already specified, no need to resolve the 819 * address, only set the port. 820 */ 821 /* Do nothing */ 822 813 823 } else { 814 824 … … 867 877 pjsua_transport_config config; 868 878 pj_sock_t sock = PJ_INVALID_SOCKET; 879 pj_sockaddr_in bound_addr; 869 880 pj_sockaddr_in pub_addr; 870 881 pjsip_host_port addr_name; … … 876 887 } 877 888 878 /* Create the socket and possibly resolve the address with STUN */ 879 status = create_sip_udp_sock(cfg->ip_addr, cfg->port, cfg->use_stun, 880 &cfg->stun_config, &sock, &pub_addr); 889 /* Initialize bound address, if any */ 890 bound_addr.sin_addr.s_addr = PJ_INADDR_ANY; 891 if (cfg->bound_addr.slen) { 892 status = pj_sockaddr_in_set_str_addr(&bound_addr,&cfg->bound_addr); 893 if (status != PJ_SUCCESS) { 894 pjsua_perror(THIS_FILE, 895 "Unable to resolve transport bound address", 896 status); 897 goto on_return; 898 } 899 } 900 901 /* Initialize the public address from the config, if any */ 902 pj_sockaddr_in_init(&pub_addr, NULL, (pj_uint16_t)cfg->port); 903 if (cfg->public_addr.slen) { 904 status = pj_sockaddr_in_set_str_addr(&pub_addr, &cfg->public_addr); 905 if (status != PJ_SUCCESS) { 906 pjsua_perror(THIS_FILE, 907 "Unable to resolve transport public address", 908 status); 909 goto on_return; 910 } 911 } 912 913 /* Create the socket and possibly resolve the address with STUN 914 * (only when public address is not specified). 915 */ 916 status = create_sip_udp_sock(bound_addr.sin_addr, cfg->port, 917 cfg->use_stun, &cfg->stun_config, 918 &sock, &pub_addr); 881 919 if (status != PJ_SUCCESS) 882 920 goto on_return; … … 907 945 */ 908 946 pjsua_transport_config config; 947 pjsip_host_port a_name; 909 948 pjsip_tpfactory *tcp; 910 949 pj_sockaddr_in local_addr; … … 922 961 local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port); 923 962 924 if (cfg->ip_addr.s_addr) 925 local_addr.sin_addr.s_addr = cfg->ip_addr.s_addr; 963 if (cfg->bound_addr.slen) { 964 status = pj_sockaddr_in_set_str_addr(&local_addr,&cfg->bound_addr); 965 if (status != PJ_SUCCESS) { 966 pjsua_perror(THIS_FILE, 967 "Unable to resolve transport bound address", 968 status); 969 goto on_return; 970 } 971 } 972 973 /* Init published name */ 974 pj_bzero(&a_name, sizeof(pjsip_host_port)); 975 if (cfg->public_addr.slen) 976 a_name.host = cfg->public_addr; 926 977 927 978 /* Create the TCP transport */ 928 status = pjsip_tcp_transport_start (pjsua_var.endpt, &local_addr, 1,929 &tcp);979 status = pjsip_tcp_transport_start2(pjsua_var.endpt, &local_addr, 980 &a_name, 1, &tcp); 930 981 931 982 if (status != PJ_SUCCESS) { … … 1030 1081 { 1031 1082 struct transport_data *t = &pjsua_var.tpdata[id]; 1083 pj_status_t status; 1032 1084 1033 1085 pj_bzero(info, sizeof(*info)); … … 1060 1112 info->usage_count = pj_atomic_get(tp->ref_cnt); 1061 1113 1114 status = PJ_SUCCESS; 1115 1062 1116 } else if (pjsua_var.tpdata[id].type == PJSIP_TRANSPORT_TCP) { 1063 1117 … … 1079 1133 info->usage_count = 0; 1080 1134 1135 status = PJ_SUCCESS; 1136 1137 } else { 1138 pj_assert(!"Unsupported transport"); 1139 status = PJ_EINVALIDOP; 1081 1140 } 1082 1141 … … 1084 1143 PJSUA_UNLOCK(); 1085 1144 1086 return PJ_EINVALIDOP;1145 return status; 1087 1146 } 1088 1147 … … 1121 1180 PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL); 1122 1181 1123 1124 /* To be done!! */ 1125 PJ_UNUSED_ARG(force); 1126 1127 PJ_TODO(pjsua_transport_close); 1128 1182 /* Note: destroy() may not work if there are objects still referencing 1183 * the transport. 1184 */ 1185 if (force) { 1186 switch (pjsua_var.tpdata[id].type) { 1187 case PJSIP_TRANSPORT_UDP: 1188 return pjsip_transport_destroy(pjsua_var.tpdata[id].data.tp); 1189 case PJSIP_TRANSPORT_TCP: 1190 break; 1191 } 1192 1193 } else { 1194 switch (pjsua_var.tpdata[id].type) { 1195 case PJSIP_TRANSPORT_UDP: 1196 return pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp); 1197 case PJSIP_TRANSPORT_TCP: 1198 return (*pjsua_var.tpdata[id].data.factory->destroy) 1199 (pjsua_var.tpdata[id].data.factory); 1200 } 1201 } 1202 1203 /* Unreachable */ 1204 pj_assert(!"Unknown transport"); 1129 1205 return PJ_EINVALIDOP; 1130 1206 } -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r721 r742 210 210 int i; 211 211 static pj_uint16_t rtp_port; 212 pj_sockaddr_in bound_addr; 212 213 pj_sockaddr_in mapped_addr[2]; 213 214 pj_status_t status = PJ_SUCCESS; … … 220 221 sock[i] = PJ_INVALID_SOCKET; 221 222 223 bound_addr.sin_addr.s_addr = PJ_INADDR_ANY; 224 if (cfg->bound_addr.slen) { 225 status = pj_sockaddr_in_set_str_addr(&bound_addr, &cfg->bound_addr); 226 if (status != PJ_SUCCESS) { 227 pjsua_perror(THIS_FILE, "Unable to resolve transport bind address", 228 status); 229 return status; 230 } 231 } 222 232 223 233 /* Loop retry to bind RTP and RTCP sockets. */ … … 231 241 } 232 242 233 status = pj_sock_bind_in(sock[0], cfg->ip_addr.s_addr, rtp_port); 243 status = pj_sock_bind_in(sock[0], bound_addr.sin_addr.s_addr, 244 rtp_port); 234 245 if (status != PJ_SUCCESS) { 235 246 pj_sock_close(sock[0]); … … 246 257 } 247 258 248 status = pj_sock_bind_in(sock[1], cfg->ip_addr.s_addr,259 status = pj_sock_bind_in(sock[1], bound_addr.sin_addr.s_addr, 249 260 (pj_uint16_t)(rtp_port+1)); 250 261 if (status != PJ_SUCCESS) { … … 286 297 sock[1] = PJ_INVALID_SOCKET; 287 298 299 } else if (cfg->public_addr.slen) { 300 301 status = pj_sockaddr_in_init(&mapped_addr[0], &cfg->public_addr, 302 (pj_uint16_t)rtp_port); 303 if (status != PJ_SUCCESS) 304 goto on_error; 305 306 status = pj_sockaddr_in_init(&mapped_addr[1], &cfg->public_addr, 307 (pj_uint16_t)(rtp_port+1)); 308 if (status != PJ_SUCCESS) 309 goto on_error; 310 311 break; 312 288 313 } else { 289 314 pj_in_addr addr;
Note: See TracChangeset
for help on using the changeset viewer.