Ignore:
Timestamp:
Aug 7, 2012 2:18:15 AM (12 years ago)
Author:
bennylp
Message:

Fixed #1412: Account specific NAT settings: STUN, ICE, and TURN

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_transport.c

    r4094 r4218  
    2525#include <pjsip/sip_errno.h> 
    2626#include <pjsip/sip_module.h> 
     27#include <pj/addr_resolv.h> 
    2728#include <pj/except.h> 
    2829#include <pj/os.h> 
     
    10811082} 
    10821083 
     1084PJ_DECL(void) pjsip_tpmgr_fla2_param_default(pjsip_tpmgr_fla2_param *prm) 
     1085{ 
     1086    pj_bzero(prm, sizeof(*prm)); 
     1087} 
    10831088 
    10841089/***************************************************************************** 
     
    11391144} 
    11401145 
    1141  
     1146/* Get the interface to send packet to the specified address */ 
     1147static pj_status_t get_net_interface(pjsip_transport_type_e tp_type, 
     1148                                     const pj_str_t *dst, 
     1149                                     pj_str_t *itf_str_addr) 
     1150{ 
     1151    int af; 
     1152    pj_sockaddr itf_addr; 
     1153    pj_status_t status; 
     1154 
     1155    af = (tp_type & PJSIP_TRANSPORT_IPV6)? PJ_AF_INET6 : PJ_AF_INET; 
     1156    status = pj_getipinterface(af, dst, &itf_addr, PJ_FALSE, NULL); 
     1157    if (status != PJ_SUCCESS) 
     1158        return status; 
     1159 
     1160    /* Print address */ 
     1161    pj_sockaddr_print(&itf_addr, itf_str_addr->ptr, 
     1162                      PJ_INET6_ADDRSTRLEN, 0); 
     1163    itf_str_addr->slen = pj_ansi_strlen(itf_str_addr->ptr); 
     1164 
     1165    return PJ_SUCCESS; 
     1166} 
    11421167 
    11431168/* 
     
    11501175 * the transport type in the request. 
    11511176 */ 
     1177PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr2(pjsip_tpmgr *tpmgr, 
     1178                                                 pj_pool_t *pool, 
     1179                                                 pjsip_tpmgr_fla2_param *prm) 
     1180{ 
     1181    char tmp_buf[PJ_INET6_ADDRSTRLEN+10]; 
     1182    pj_str_t tmp_str = { tmp_buf, 0 }; 
     1183    pj_status_t status = PJSIP_EUNSUPTRANSPORT; 
     1184    unsigned flag; 
     1185 
     1186    /* Sanity checks */ 
     1187    PJ_ASSERT_RETURN(tpmgr && pool && prm, PJ_EINVAL); 
     1188 
     1189    prm->ret_addr.slen = 0; 
     1190    prm->ret_port = 0; 
     1191    prm->ret_tp = NULL; 
     1192 
     1193    flag = pjsip_transport_get_flag_from_type(prm->tp_type); 
     1194 
     1195    if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_TRANSPORT && 
     1196        prm->tp_sel->u.transport) 
     1197    { 
     1198        const pjsip_transport *tp = prm->tp_sel->u.transport; 
     1199        if (prm->local_if) { 
     1200            status = get_net_interface(tp->key.type, &prm->dst_host, 
     1201                                       &tmp_str); 
     1202            if (status != PJ_SUCCESS) 
     1203                goto on_return; 
     1204            pj_strdup(pool, &prm->ret_addr, &tmp_str); 
     1205            prm->ret_port = pj_sockaddr_get_port(&tp->local_addr); 
     1206            prm->ret_tp = tp; 
     1207        } else { 
     1208            pj_strdup(pool, &prm->ret_addr, &tp->local_name.host); 
     1209            prm->ret_port = tp->local_name.port; 
     1210        } 
     1211        status = PJ_SUCCESS; 
     1212 
     1213    } else if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_LISTENER && 
     1214               prm->tp_sel->u.listener) 
     1215    { 
     1216        if (prm->local_if) { 
     1217            status = get_net_interface(prm->tp_sel->u.listener->type, 
     1218                                       &prm->dst_host, &tmp_str); 
     1219            if (status != PJ_SUCCESS) 
     1220                goto on_return; 
     1221            pj_strdup(pool, &prm->ret_addr, &tmp_str); 
     1222        } else { 
     1223            pj_strdup(pool, &prm->ret_addr, 
     1224                      &prm->tp_sel->u.listener->addr_name.host); 
     1225        } 
     1226        prm->ret_port = prm->tp_sel->u.listener->addr_name.port; 
     1227        status = PJ_SUCCESS; 
     1228 
     1229    } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { 
     1230        pj_sockaddr remote; 
     1231        int addr_len; 
     1232        pjsip_transport *tp; 
     1233 
     1234        pj_bzero(&remote, sizeof(remote)); 
     1235        if (prm->tp_type & PJSIP_TRANSPORT_IPV6) { 
     1236            addr_len = sizeof(pj_sockaddr_in6); 
     1237            remote.addr.sa_family = pj_AF_INET6(); 
     1238        } else { 
     1239            addr_len = sizeof(pj_sockaddr_in); 
     1240            remote.addr.sa_family = pj_AF_INET(); 
     1241        } 
     1242 
     1243        status = pjsip_tpmgr_acquire_transport(tpmgr, prm->tp_type, &remote, 
     1244                                               addr_len, NULL, &tp); 
     1245 
     1246        if (status == PJ_SUCCESS) { 
     1247            if (prm->local_if) { 
     1248                status = get_net_interface(tp->key.type, &prm->dst_host, 
     1249                                           &tmp_str); 
     1250                if (status != PJ_SUCCESS) 
     1251                    goto on_return; 
     1252                pj_strdup(pool, &prm->ret_addr, &tmp_str); 
     1253                prm->ret_port = pj_sockaddr_get_port(&tp->local_addr); 
     1254                prm->ret_tp = tp; 
     1255            } else { 
     1256                pj_strdup(pool, &prm->ret_addr, &tp->local_name.host); 
     1257                prm->ret_port = tp->local_name.port; 
     1258            } 
     1259 
     1260            pjsip_transport_dec_ref(tp); 
     1261        } 
     1262 
     1263    } else { 
     1264        /* For connection oriented transport, enum the factories */ 
     1265        pjsip_tpfactory *f; 
     1266 
     1267        pj_lock_acquire(tpmgr->lock); 
     1268 
     1269        f = tpmgr->factory_list.next; 
     1270        while (f != &tpmgr->factory_list) { 
     1271            if (f->type == prm->tp_type) 
     1272                break; 
     1273            f = f->next; 
     1274        } 
     1275 
     1276        if (f != &tpmgr->factory_list) { 
     1277            if (prm->local_if) { 
     1278                status = get_net_interface(f->type, &prm->dst_host, 
     1279                                           &tmp_str); 
     1280                if (status != PJ_SUCCESS) 
     1281                    goto on_return; 
     1282                pj_strdup(pool, &prm->ret_addr, &tmp_str); 
     1283            } else { 
     1284                pj_strdup(pool, &prm->ret_addr, &f->addr_name.host); 
     1285            } 
     1286            prm->ret_port = f->addr_name.port; 
     1287            status = PJ_SUCCESS; 
     1288        } 
     1289        pj_lock_release(tpmgr->lock); 
     1290    } 
     1291 
     1292on_return: 
     1293    return status; 
     1294} 
     1295 
    11521296PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, 
    11531297                                                 pj_pool_t *pool, 
     
    11571301                                                 int *port) 
    11581302{ 
    1159     pj_status_t status = PJSIP_EUNSUPTRANSPORT; 
    1160     unsigned flag; 
    1161  
    1162     /* Sanity checks */ 
    1163     PJ_ASSERT_RETURN(tpmgr && pool && ip_addr && port, PJ_EINVAL); 
    1164  
    1165     ip_addr->slen = 0; 
    1166     *port = 0; 
    1167  
    1168     flag = pjsip_transport_get_flag_from_type(type); 
    1169  
    1170     if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT && 
    1171         sel->u.transport) 
    1172     { 
    1173         pj_strdup(pool, ip_addr, &sel->u.transport->local_name.host); 
    1174         *port = sel->u.transport->local_name.port; 
    1175         status = PJ_SUCCESS; 
    1176  
    1177     } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && 
    1178                sel->u.listener) 
    1179     { 
    1180         pj_strdup(pool, ip_addr, &sel->u.listener->addr_name.host); 
    1181         *port = sel->u.listener->addr_name.port; 
    1182         status = PJ_SUCCESS; 
    1183  
    1184     } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { 
    1185          
    1186         pj_sockaddr remote; 
    1187         int addr_len; 
    1188         pjsip_transport *tp; 
    1189  
    1190         pj_bzero(&remote, sizeof(remote)); 
    1191         if (type & PJSIP_TRANSPORT_IPV6) { 
    1192             addr_len = sizeof(pj_sockaddr_in6); 
    1193             remote.addr.sa_family = pj_AF_INET6(); 
    1194         } else { 
    1195             addr_len = sizeof(pj_sockaddr_in); 
    1196             remote.addr.sa_family = pj_AF_INET(); 
    1197         } 
    1198  
    1199         status = pjsip_tpmgr_acquire_transport(tpmgr, type, &remote, 
    1200                                                addr_len, NULL, &tp); 
    1201  
    1202         if (status == PJ_SUCCESS) { 
    1203             pj_strdup(pool, ip_addr, &tp->local_name.host); 
    1204             *port = tp->local_name.port; 
    1205             status = PJ_SUCCESS; 
    1206  
    1207             pjsip_transport_dec_ref(tp); 
    1208         } 
    1209  
    1210     } else { 
    1211         /* For connection oriented transport, enum the factories */ 
    1212         pjsip_tpfactory *f; 
    1213  
    1214         pj_lock_acquire(tpmgr->lock); 
    1215  
    1216         f = tpmgr->factory_list.next; 
    1217         while (f != &tpmgr->factory_list) { 
    1218             if (f->type == type) 
    1219                 break; 
    1220             f = f->next; 
    1221         } 
    1222  
    1223         if (f != &tpmgr->factory_list) { 
    1224             pj_strdup(pool, ip_addr, &f->addr_name.host); 
    1225             *port = f->addr_name.port; 
    1226             status = PJ_SUCCESS; 
    1227         } 
    1228         pj_lock_release(tpmgr->lock); 
    1229     } 
    1230  
    1231     return status; 
     1303    pjsip_tpmgr_fla2_param prm; 
     1304    pj_status_t status; 
     1305 
     1306    pjsip_tpmgr_fla2_param_default(&prm); 
     1307    prm.tp_type = type; 
     1308    prm.tp_sel = sel; 
     1309 
     1310    status = pjsip_tpmgr_find_local_addr2(tpmgr, pool, &prm); 
     1311    if (status != PJ_SUCCESS) 
     1312        return status; 
     1313 
     1314    *ip_addr = prm.ret_addr; 
     1315    *port = prm.ret_port; 
     1316 
     1317    return PJ_SUCCESS; 
    12321318} 
    12331319 
Note: See TracChangeset for help on using the changeset viewer.