PJStunTurn::PJStunTurn() { if (PJ_SUCCESS != pjnath_init()) { g_warning("cannot init pjnath"); return; } pj_ice_strans_cfg_default(&ice_cfg_); pj_timer_heap_create(PJSIP::this_->pool_, 100, &ice_cfg_.stun_cfg.timer_heap); pj_ioqueue_create(PJSIP::this_->pool_, 512, &ice_cfg_.stun_cfg.ioqueue); ice_cfg_.stun_cfg.pf = PJSIP::this_->pool_->factory; if (PJ_SUCCESS != pj_thread_create(PJSIP::this_->pool_, "switcherSIP", &worker_thread, this, 0, 0, &thread_)) { g_warning("STUN TURN thread creating failed"); return; } ice_cfg_.af = pj_AF_INET(); ice_cfg_.stun.cfg.max_pkt_size = 8192; ice_cfg_.turn.cfg.max_pkt_size = 8192; ice_cfg_.opt.aggressive = PJ_FALSE; ice_cfg_.stun_cfg.rto_msec = 500; // set stun/turn config SIPPlugin::this_->install_method( "Set STUN/TURN parameters", // long name "set_stun_turn", // name "Set STUN/TURN configuration", // description "the server(s) are reachable", // return description Method::make_arg_description("STUN server address", // long name "stun", // name "string", // description "TURN server address", "turn", "string", "TURN user name", "turn_user", "string", "TURN user password", "turn_pass", "string", nullptr), (Method::method_ptr)&set_stun_turn, G_TYPE_BOOLEAN, Method::make_arg_type_description( G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, nullptr), this); }
pj_status_t natclient_init(ice_trans_t *icetrans, ice_option_t opt) { pj_status_t status; /* Initialize the libraries before anything else */ CHECK( pj_init(), icetrans ); CHECK( pjlib_util_init(), icetrans ); CHECK( pjnath_init(), icetrans ); #if 0 //FIXME: consider if we need to log if (natclient.opt.log_file) { icetrans->log_fhnd = fopen(natclient.opt.log_file, "a"); pj_log_set_log_func(&log_func); } #endif pj_caching_pool_init(&icetrans->cp, NULL, 0); /* Init our ICE settings with null values */ pj_ice_strans_cfg_default(&icetrans->ice_cfg); icetrans->ice_cfg.stun_cfg.pf = &icetrans->cp.factory; /* Create application memory pool */ icetrans->pool = pj_pool_create(&icetrans->cp.factory, "natclient", 512, 512, NULL); /* Create timer heap for timer stuff */ CHECK( pj_timer_heap_create(icetrans->pool, 100, &icetrans->ice_cfg.stun_cfg.timer_heap), icetrans ); /* and create ioqueue for network I/O stuff */ CHECK( pj_ioqueue_create(icetrans->pool, 16, &icetrans->ice_cfg.stun_cfg.ioqueue), icetrans ); /* something must poll the timer heap and ioqueue, * unless we're on Symbian where the timer heap and ioqueue run * on themselves. */ CHECK( pj_thread_create(icetrans->pool, "natclient", &natclient_worker_thread, icetrans, 0, 0, &icetrans->thread), icetrans ); icetrans->ice_cfg.af = pj_AF_INET(); /* Create DNS resolver if nameserver is set */ if (opt.ns.slen) { CHECK( pj_dns_resolver_create(&icetrans->cp.factory, "resolver", 0, icetrans->ice_cfg.stun_cfg.timer_heap, icetrans->ice_cfg.stun_cfg.ioqueue, &icetrans->ice_cfg.resolver), icetrans ); CHECK( pj_dns_resolver_set_ns(icetrans->ice_cfg.resolver, 1, &opt.ns, NULL) , icetrans); } /* -= Start initializing ICE stream transport config =- */ /* Maximum number of host candidates */ if (opt.max_host != -1) icetrans->ice_cfg.stun.max_host_cands = opt.max_host; /* Nomination strategy */ if (opt.regular) icetrans->ice_cfg.opt.aggressive = PJ_FALSE; else icetrans->ice_cfg.opt.aggressive = PJ_TRUE; /* Configure STUN/srflx candidate resolution */ if (opt.stun_srv.slen) { char *pos; /* Command line option may contain port number */ if ((pos=pj_strchr(&opt.stun_srv, ':')) != NULL) { icetrans->ice_cfg.stun.server.ptr = opt.stun_srv.ptr; icetrans->ice_cfg.stun.server.slen = (pos - opt.stun_srv.ptr); icetrans->ice_cfg.stun.port = (pj_uint16_t)atoi(pos+1); } else { icetrans->ice_cfg.stun.server = opt.stun_srv; icetrans->ice_cfg.stun.port = PJ_STUN_PORT; } /* For this demo app, configure longer STUN keep-alive time * so that it does't clutter the screen output. */ icetrans->ice_cfg.stun.cfg.ka_interval = KA_INTERVAL; } /* Configure TURN candidate */ if (opt.turn_srv.slen) { char *pos; /* Command line option may contain port number */ if ((pos=pj_strchr(&opt.turn_srv, ':')) != NULL) { icetrans->ice_cfg.turn.server.ptr = opt.turn_srv.ptr; icetrans->ice_cfg.turn.server.slen = (pos - opt.turn_srv.ptr); icetrans->ice_cfg.turn.port = (pj_uint16_t)atoi(pos+1); } else { icetrans->ice_cfg.turn.server = opt.turn_srv; icetrans->ice_cfg.turn.port = PJ_STUN_PORT; } /* TURN credential */ icetrans->ice_cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC; icetrans->ice_cfg.turn.auth_cred.data.static_cred.username = opt.turn_username; icetrans->ice_cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; icetrans->ice_cfg.turn.auth_cred.data.static_cred.data = opt.turn_password; /* Connection type to TURN server */ if (opt.turn_tcp) icetrans->ice_cfg.turn.conn_type = PJ_TURN_TP_TCP; else icetrans->ice_cfg.turn.conn_type = PJ_TURN_TP_UDP; /* For this demo app, configure longer keep-alive time * so that it does't clutter the screen output. */ icetrans->ice_cfg.turn.alloc_param.ka_interval = KA_INTERVAL; } /* -= That's it for now, initialization is complete =- */ return PJ_SUCCESS; }
/* Create ICE stream transport */ static int create_ice_strans(struct test_sess *test_sess, struct ice_ept *ept, pj_ice_strans **p_ice) { pj_ice_strans *ice; pj_ice_strans_cb ice_cb; pj_ice_strans_cfg ice_cfg; pj_sockaddr hostip; char serverip[PJ_INET6_ADDRSTRLEN]; pj_status_t status; status = pj_gethostip(pj_AF_INET(), &hostip); if (status != PJ_SUCCESS) return -1030; pj_sockaddr_print(&hostip, serverip, sizeof(serverip), 0); /* Init callback structure */ pj_bzero(&ice_cb, sizeof(ice_cb)); ice_cb.on_rx_data = &ice_on_rx_data; ice_cb.on_ice_complete = &ice_on_ice_complete; /* Init ICE stream transport configuration structure */ pj_ice_strans_cfg_default(&ice_cfg); pj_memcpy(&ice_cfg.stun_cfg, test_sess->stun_cfg, sizeof(pj_stun_config)); if ((ept->cfg.enable_stun & SRV)==SRV || (ept->cfg.enable_turn & SRV)==SRV) ice_cfg.resolver = test_sess->resolver; if (ept->cfg.enable_stun & YES) { if ((ept->cfg.enable_stun & SRV) == SRV) { ice_cfg.stun.server = pj_str(SRV_DOMAIN); } else { ice_cfg.stun.server = pj_str(serverip); } ice_cfg.stun.port = STUN_SERVER_PORT; } if (ept->cfg.enable_host == 0) { ice_cfg.stun.max_host_cands = 0; } else { //ice_cfg.stun.no_host_cands = PJ_FALSE; ice_cfg.stun.loop_addr = PJ_TRUE; } if (ept->cfg.enable_turn & YES) { if ((ept->cfg.enable_turn & SRV) == SRV) { ice_cfg.turn.server = pj_str(SRV_DOMAIN); } else { ice_cfg.turn.server = pj_str(serverip); } ice_cfg.turn.port = TURN_SERVER_PORT; ice_cfg.turn.conn_type = PJ_TURN_TP_UDP; ice_cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC; ice_cfg.turn.auth_cred.data.static_cred.realm = pj_str(SRV_DOMAIN); if (ept->cfg.client_flag & WRONG_TURN) ice_cfg.turn.auth_cred.data.static_cred.username = pj_str("xxx"); else ice_cfg.turn.auth_cred.data.static_cred.username = pj_str(TURN_USERNAME); ice_cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; ice_cfg.turn.auth_cred.data.static_cred.data = pj_str(TURN_PASSWD); } /* Create ICE stream transport */ status = pj_ice_strans_create(NULL, &ice_cfg, ept->cfg.comp_cnt, (void*)ept, &ice_cb, &ice); if (status != PJ_SUCCESS) { app_perror(INDENT "err: pj_ice_strans_create()", status); return status; } pj_create_unique_string(test_sess->pool, &ept->ufrag); pj_create_unique_string(test_sess->pool, &ept->pass); /* Looks alright */ *p_ice = ice; return PJ_SUCCESS; }
int krx_ice_init(krx_ice* k) { pj_status_t r; if(!k) { return -1; } /* initialize pj */ r = pj_init(); CHECK_PJ_STATUS(r, "Error: cannot initialize pj.\n", -2); r = pjlib_util_init(); CHECK_PJ_STATUS(r, "Error: cannot initialize pj-util.\n", -3); r = pjnath_init(); CHECK_PJ_STATUS(r, "Error: cannot initialize pjnath.\n", -4); /* create memory pool */ pj_caching_pool_init(&k->caching_pool, NULL, 0); /* initialize the ice settings */ pj_ice_strans_cfg_default(&k->ice_cfg); /* create the pool */ k->pool = pj_pool_create(&k->caching_pool.factory, "krx_ice_pjnath", 512, 512, NULL); /* 512 = initial size, 512 = incremental size */ if(!k->pool) { printf("Error: cannot create pool.\n"); return -5; } k->ice_cfg.stun_cfg.pf = &k->caching_pool.factory; /* create heap for timers */ r = pj_timer_heap_create(k->pool, 100, &k->ice_cfg.stun_cfg.timer_heap); CHECK_PJ_STATUS(r, "Error: cannot create timer heap.\n", -6); /* create ioqueue for network I/O */ r = pj_ioqueue_create(k->pool, 16, &k->ice_cfg.stun_cfg.ioqueue); CHECK_PJ_STATUS(r, "Error: cannot create ioqueue.\n", -7); /* create managing thread */ r = pj_thread_create(k->pool, "krx_ice_pjnath", &krx_ice_worker_thread, k, 0, 0, &k->thread); CHECK_PJ_STATUS(r, "Error: cannot create managing thread.", -8); k->ice_cfg.af = pj_AF_INET(); /* @todo(roxlu): we could add a nameserver */ k->ice_cfg.opt.aggressive = PJ_FALSE; /* @todo(roxlu): read up the aggressive flag in ice_cfg. */ /* default configs */ k->max_hosts = 4; k->ncomp = 4; /* initialize the callbacks */ pj_bzero(&k->ice_cb, sizeof(k->ice_cb)); k->ice_cb.on_rx_data = krx_ice_on_rx_data; k->ice_cb.on_ice_complete = krx_ice_on_complete; /* sdp info */ k->ice_ufrag = NULL; k->ice_pwd = NULL; return 0; }