亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ice_strans.c

?? 一個開源的sip源代碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* $Id: ice_strans.c 1298 2007-05-23 14:54:48Z bennylp $ */
/* 
 * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjnath/ice_strans.h>
#include <pjnath/errno.h>
#include <pj/addr_resolv.h>
#include <pj/assert.h>
#include <pj/ip_helper.h>
#include <pj/log.h>
#include <pj/pool.h>
#include <pj/rand.h>
#include <pj/string.h>


#if 0
#  define TRACE_PKT(expr)	    PJ_LOG(5,expr)
#else
#  define TRACE_PKT(expr)
#endif



/* ICE callbacks */
static void	   on_ice_complete(pj_ice_sess *ice, pj_status_t status);
static pj_status_t ice_tx_pkt(pj_ice_sess *ice, 
			      unsigned comp_id,
			      const void *pkt, pj_size_t size,
			      const pj_sockaddr_t *dst_addr,
			      unsigned dst_addr_len);
static void	   ice_rx_data(pj_ice_sess *ice, 
			      unsigned comp_id, 
			      void *pkt, pj_size_t size,
			      const pj_sockaddr_t *src_addr,
			      unsigned src_addr_len);

/* Ioqueue callback */
static void on_read_complete(pj_ioqueue_key_t *key, 
                             pj_ioqueue_op_key_t *op_key, 
                             pj_ssize_t bytes_read);

static void destroy_component(pj_ice_strans_comp *comp);
static void destroy_ice_st(pj_ice_strans *ice_st, pj_status_t reason);


/* STUN session callback */
static pj_status_t stun_on_send_msg(pj_stun_session *sess,
				    const void *pkt,
				    pj_size_t pkt_size,
				    const pj_sockaddr_t *dst_addr,
				    unsigned addr_len);
static void stun_on_request_complete(pj_stun_session *sess,
				     pj_status_t status,
				     pj_stun_tx_data *tdata,
				     const pj_stun_msg *response,
				     const pj_sockaddr_t *src_addr,
				     unsigned src_addr_len);

/* Keep-alive timer */
static void start_ka_timer(pj_ice_strans *ice_st);
static void stop_ka_timer(pj_ice_strans *ice_st);

/* Utility: print error */
#define ice_st_perror(ice_st,msg,rc) pjnath_perror(ice_st->obj_name,msg,rc)

/* 
 * Create ICE stream transport 
 */
PJ_DECL(pj_status_t) pj_ice_strans_create(pj_stun_config *stun_cfg,
					  const char *name,
					  unsigned comp_cnt,
					  void *user_data,
					  const pj_ice_strans_cb *cb,
					  pj_ice_strans **p_ice_st)
{
    pj_pool_t *pool;
    pj_ice_strans *ice_st;

    PJ_ASSERT_RETURN(stun_cfg && comp_cnt && cb && p_ice_st, PJ_EINVAL);
    PJ_ASSERT_RETURN(stun_cfg->ioqueue && stun_cfg->timer_heap, PJ_EINVAL);

    if (name == NULL)
	name = "icstr%p";

    pool = pj_pool_create(stun_cfg->pf, name, 1000, 512, NULL);
    ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans);
    ice_st->pool = pool;
    pj_memcpy(ice_st->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME);
    ice_st->user_data = user_data;
    
    ice_st->comp_cnt = comp_cnt;
    ice_st->comp = (pj_ice_strans_comp**) pj_pool_calloc(pool, comp_cnt, 
						     sizeof(void*));

    pj_memcpy(&ice_st->cb, cb, sizeof(*cb));
    pj_memcpy(&ice_st->stun_cfg, stun_cfg, sizeof(*stun_cfg));


    PJ_LOG(4,(ice_st->obj_name, "ICE stream transport created"));

    *p_ice_st = ice_st;
    return PJ_SUCCESS;
}

/* Destroy ICE */
static void destroy_ice_st(pj_ice_strans *ice_st, pj_status_t reason)
{
    unsigned i;
    char obj_name[PJ_MAX_OBJ_NAME];

    if (reason == PJ_SUCCESS) {
	pj_memcpy(obj_name, ice_st->obj_name, PJ_MAX_OBJ_NAME);
	PJ_LOG(4,(obj_name, "ICE stream transport shutting down"));
    }

    /* Kill keep-alive timer, if any */
    stop_ka_timer(ice_st);

    /* Destroy ICE if we have ICE */
    if (ice_st->ice) {
	pj_ice_sess_destroy(ice_st->ice);
	ice_st->ice = NULL;
    }

    /* Destroy all components */
    for (i=0; i<ice_st->comp_cnt; ++i) {
	if (ice_st->comp[i]) {
	    destroy_component(ice_st->comp[i]);
	    ice_st->comp[i] = NULL;
	}
    }
    ice_st->comp_cnt = 0;

    /* Done */
    pj_pool_release(ice_st->pool);

    if (reason == PJ_SUCCESS) {
	PJ_LOG(4,(obj_name, "ICE stream transport destroyed"));
    }
}

/*
 * Destroy ICE stream transport.
 */
PJ_DEF(pj_status_t) pj_ice_strans_destroy(pj_ice_strans *ice_st)
{
    destroy_ice_st(ice_st, PJ_SUCCESS);
    return PJ_SUCCESS;
}

/*
 * Resolve STUN server
 */
PJ_DEF(pj_status_t) pj_ice_strans_set_stun_domain(pj_ice_strans *ice_st,
						  pj_dns_resolver *resolver,
						  const pj_str_t *domain)
{
    /* Yeah, TODO */
    PJ_UNUSED_ARG(ice_st);
    PJ_UNUSED_ARG(resolver);
    PJ_UNUSED_ARG(domain);
    return -1;
}

/*
 * Set STUN server address.
 */
PJ_DEF(pj_status_t) pj_ice_strans_set_stun_srv( pj_ice_strans *ice_st,
						const pj_sockaddr_in *stun_srv,
						const pj_sockaddr_in *turn_srv)
{
    PJ_ASSERT_RETURN(ice_st, PJ_EINVAL);
    /* Must not have pending resolver job */
    PJ_ASSERT_RETURN(ice_st->has_rjob==PJ_FALSE, PJ_EINVALIDOP);

    if (stun_srv) {
	pj_memcpy(&ice_st->stun_srv, stun_srv, sizeof(pj_sockaddr_in));
    } else {
	pj_bzero(&ice_st->stun_srv, sizeof(pj_sockaddr_in));
    }

    if (turn_srv) {
	pj_memcpy(&ice_st->turn_srv, turn_srv, sizeof(pj_sockaddr_in));
    } else {
	pj_bzero(&ice_st->turn_srv, sizeof(pj_sockaddr_in));
    }

    return PJ_SUCCESS;
}

/* Add new candidate */
static pj_status_t add_cand( pj_ice_strans *ice_st,
			     pj_ice_strans_comp *comp,
			     unsigned comp_id,
			     pj_ice_cand_type type,
			     pj_uint16_t local_pref,
			     const pj_sockaddr_in *addr,
			     pj_bool_t set_default)
{
    pj_ice_strans_cand *cand;
    unsigned i;

    PJ_ASSERT_RETURN(ice_st && comp && addr, PJ_EINVAL);
    PJ_ASSERT_RETURN(comp->cand_cnt < PJ_ICE_ST_MAX_CAND, PJ_ETOOMANY);

    /* Check that we don't have candidate with the same
     * address.
     */
    for (i=0; i<comp->cand_cnt; ++i) {
	if (pj_memcmp(addr, &comp->cand_list[i].addr, 
		      sizeof(pj_sockaddr_in))==0)
	{
	    /* Duplicate */
	    PJ_LOG(5,(ice_st->obj_name, "Duplicate candidate not added"));
	    return PJ_SUCCESS;
	}
    }

    cand = &comp->cand_list[comp->cand_cnt];

    pj_bzero(cand, sizeof(*cand));
    cand->type = type;
    cand->status = PJ_SUCCESS;
    pj_memcpy(&cand->addr, addr, sizeof(pj_sockaddr_in));
    cand->ice_cand_id = -1;
    cand->local_pref = local_pref;
    pj_ice_calc_foundation(ice_st->pool, &cand->foundation, type, 
			   &comp->local_addr);

    if (set_default) 
	comp->default_cand = comp->cand_cnt;

    PJ_LOG(5,(ice_st->obj_name, 
	      "Candidate %s:%d (type=%s) added to component %d",
	      pj_inet_ntoa(addr->sin_addr),
	      (int)pj_ntohs(addr->sin_port), 
	      pj_ice_get_cand_type_name(type),
	      comp_id));
    
    comp->cand_cnt++;
    return PJ_SUCCESS;
}

/*  Create new component (i.e. socket)  */
static pj_status_t create_component(pj_ice_strans *ice_st,
				    unsigned comp_id,
				    pj_uint32_t options,
				    const pj_sockaddr_in *addr,
				    pj_ice_strans_comp **p_comp)
{
    enum { MAX_RETRY=100, PORT_INC=2 };
    pj_ioqueue_callback ioqueue_cb;
    pj_ice_strans_comp *comp;
    int retry, addr_len;
    struct {
	pj_uint32_t a1, a2, a3;
    } tsx_id;
    pj_status_t status;

    comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_strans_comp);
    comp->ice_st = ice_st;
    comp->comp_id = comp_id;
    comp->options = options;
    comp->sock = PJ_INVALID_SOCKET;
    comp->last_status = PJ_SUCCESS;

    /* Create transaction ID for STUN keep alives */
    tsx_id.a1 = 0;
    tsx_id.a2 = comp_id;
    tsx_id.a3 = (pj_uint32_t) ice_st;
    pj_memcpy(comp->ka_tsx_id, &tsx_id, sizeof(comp->ka_tsx_id));

    /* Create socket */
    status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &comp->sock);
    if (status != PJ_SUCCESS)
	return status;

    /* Init address */
    if (addr) 
	pj_memcpy(&comp->local_addr, addr, sizeof(pj_sockaddr_in));
    else 
	pj_sockaddr_in_init(&comp->local_addr.ipv4, NULL, 0);

    /* Retry binding socket */
    for (retry=0; retry<MAX_RETRY; ++retry) {
	pj_uint16_t port;

	status = pj_sock_bind(comp->sock, &comp->local_addr, 
			      sizeof(pj_sockaddr_in));
	if (status == PJ_SUCCESS)
	    break;

	if (options & PJ_ICE_ST_OPT_NO_PORT_RETRY)
	    goto on_error;

	port = pj_ntohs(comp->local_addr.ipv4.sin_port);
	port += PORT_INC;
	comp->local_addr.ipv4.sin_port = pj_htons(port);
    }

    /* Get the actual port where the socket is bound to.
     * (don't care about the address, it will be retrieved later)
     */
    addr_len = sizeof(comp->local_addr);
    status = pj_sock_getsockname(comp->sock, &comp->local_addr, &addr_len);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Register to ioqueue */
    pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb));
    ioqueue_cb.on_read_complete = &on_read_complete;
    status = pj_ioqueue_register_sock(ice_st->pool, ice_st->stun_cfg.ioqueue, 
				      comp->sock, comp, &ioqueue_cb, 
				      &comp->key);
    if (status != PJ_SUCCESS)
	goto on_error;

    pj_ioqueue_op_key_init(&comp->read_op, sizeof(comp->read_op));
    pj_ioqueue_op_key_init(&comp->write_op, sizeof(comp->write_op));

    /* Kick start reading the socket */
    on_read_complete(comp->key, &comp->read_op, 0);

    /* If the socket is bound to INADDR_ANY, then lookup all interfaces in
     * the host and add them into cand_list. Otherwise if the socket is bound
     * to a specific interface, then only add that specific interface to
     * cand_list.
     */
    if (((options & PJ_ICE_ST_OPT_DONT_ADD_CAND)==0) &&
	comp->local_addr.ipv4.sin_addr.s_addr == 0) 
    {
	/* Socket is bound to INADDR_ANY */
	unsigned i, ifs_cnt;
	pj_in_addr ifs[PJ_ICE_ST_MAX_CAND-2];

	/* Reset default candidate */
	comp->default_cand = -1;

	/* Enum all IP interfaces in the host */
	ifs_cnt = PJ_ARRAY_SIZE(ifs);
	status = pj_enum_ip_interface(&ifs_cnt, ifs);
	if (status != PJ_SUCCESS)
	    goto on_error;

	/* Set default IP interface as the base address */
	status = pj_gethostip(&comp->local_addr.ipv4.sin_addr);
	if (status != PJ_SUCCESS)
	    goto on_error;

	/* Add candidate entry for each interface */
	for (i=0; i<ifs_cnt; ++i) {
	    pj_sockaddr_in cand_addr;
	    pj_bool_t set_default;
	    pj_uint16_t local_pref;

	    /* Ignore 127.0.0.0/24 address */
	    if ((pj_ntohl(ifs[i].s_addr) >> 24)==127)
		continue;

	    pj_memcpy(&cand_addr, &comp->local_addr, sizeof(pj_sockaddr_in));
	    cand_addr.sin_addr.s_addr = ifs[i].s_addr;


	    /* If the IP address is equal to local address, assign it
	     * as default candidate.
	     */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩国产综合一区二区 | 亚洲成人综合视频| 国产精品污网站| 欧美激情综合五月色丁香小说| 欧美日韩国产高清一区二区三区 | 精品少妇一区二区三区在线视频| 久久久91精品国产一区二区精品 | 国产不卡一区视频| 欧美激情一区二区三区| 欧美日韩精品高清| 欧美色精品天天在线观看视频| 国产一区二区在线观看视频| 国产精品一二三区在线| 国内精品伊人久久久久av一坑| 日本vs亚洲vs韩国一区三区二区 | 香蕉乱码成人久久天堂爱免费| 亚洲欧美一区二区三区国产精品| 国产无人区一区二区三区| 国产精品福利在线播放| 精品一区二区久久久| 欧美性欧美巨大黑白大战| 欧美一区二区视频免费观看| 国产亚洲欧美中文| 韩国午夜理伦三级不卡影院| 亚洲视频一二三区| 韩国在线一区二区| 免费视频最近日韩| 国产精品综合一区二区| 成熟亚洲日本毛茸茸凸凹| 欧美精品黑人性xxxx| 亚洲r级在线视频| 91网站黄www| 在线看一区二区| 亚洲国产高清aⅴ视频| 亚洲视频一区在线| 精品一区二区三区香蕉蜜桃| 欧美精品亚洲一区二区在线播放| 成人一二三区视频| 国产毛片精品视频| 精品久久久久一区二区国产| 91在线精品一区二区| 91福利在线播放| 欧美sm极限捆绑bd| 麻豆91在线观看| 色综合久久久久久久久| 亚洲天堂中文字幕| 51精品视频一区二区三区| 一级日本不卡的影视| 91在线播放网址| 亚洲欧美自拍偷拍| 99天天综合性| 婷婷久久综合九色综合绿巨人 | 午夜电影久久久| 不卡欧美aaaaa| 国产成人免费视频精品含羞草妖精| 91精品婷婷国产综合久久| 亚洲美女免费在线| 在线亚洲免费视频| 亚洲成a人v欧美综合天堂下载| 欧美伦理影视网| 精品在线播放午夜| 久久久久久免费| 国产suv一区二区三区88区| 亚洲精品一区二区三区精华液| 精品综合免费视频观看| 欧美日韩午夜在线| 亚洲黄色片在线观看| 强制捆绑调教一区二区| 欧美剧情电影在线观看完整版免费励志电影| 97se亚洲国产综合自在线 | 激情小说亚洲一区| 91精品国产91久久久久久一区二区 | 国产日韩视频一区二区三区| 秋霞成人午夜伦在线观看| 欧美三级日韩三级国产三级| 亚洲三级电影全部在线观看高清| 国产很黄免费观看久久| 日韩欧美的一区二区| 秋霞电影一区二区| 日韩免费性生活视频播放| 日本女人一区二区三区| 欧美一区二区在线看| 免费在线观看日韩欧美| 欧美一区二区三区视频在线| 日韩av一级片| 精品国产一区二区三区久久久蜜月 | 日韩一区在线免费观看| 99riav一区二区三区| 亚洲精品日日夜夜| 欧美日韩中文精品| 美洲天堂一区二卡三卡四卡视频| 91精品欧美综合在线观看最新| 日本不卡视频一二三区| 欧美tickle裸体挠脚心vk| 国产精品18久久久久久久久| 国产欧美日韩一区二区三区在线观看 | 777午夜精品免费视频| 免费高清视频精品| 欧美成人午夜电影| 大胆亚洲人体视频| 一区二区国产视频| 日韩精品一区二区三区老鸭窝| 久久99久久久欧美国产| 精品嫩草影院久久| 国模娜娜一区二区三区| 成人免费小视频| 在线不卡的av| 高清不卡一二三区| 亚洲欧美日韩一区二区| 9191成人精品久久| 国产成人精品午夜视频免费| 亚洲一区二区在线视频| 日韩久久久精品| 色综合天天做天天爱| 免费观看在线综合色| 日韩毛片精品高清免费| 日韩欧美久久久| 欧美伊人精品成人久久综合97| 美女视频免费一区| 亚洲精品欧美在线| 久久伊99综合婷婷久久伊| 色8久久人人97超碰香蕉987| 韩国成人精品a∨在线观看| 亚洲伦理在线免费看| 久久综合色婷婷| 在线观看日韩国产| 极品少妇xxxx偷拍精品少妇| 亚洲一区二区在线视频| 中文天堂在线一区| 精品国产亚洲一区二区三区在线观看| 91视频.com| 韩国一区二区在线观看| 日本中文在线一区| 一区二区三区在线高清| 国产精品免费视频一区| 精品奇米国产一区二区三区| 欧美日韩一区视频| 色婷婷久久久久swag精品| 风间由美性色一区二区三区| 麻豆精品视频在线观看免费| 亚洲成年人网站在线观看| 国产精品成人一区二区三区夜夜夜| 51久久夜色精品国产麻豆| 91国在线观看| 91久久线看在观草草青青| 岛国精品在线播放| 成人综合在线网站| 成人av在线一区二区| 国产伦理精品不卡| 狠狠色综合日日| 国产一区二区影院| 久久99久久99小草精品免视看| 日韩vs国产vs欧美| 日韩av电影免费观看高清完整版在线观看| 亚洲狼人国产精品| 有码一区二区三区| 亚洲另类色综合网站| 成人免费一区二区三区视频 | 男人的天堂久久精品| 蜜臀a∨国产成人精品| 美女视频网站久久| 激情综合亚洲精品| 丰满放荡岳乱妇91ww| gogogo免费视频观看亚洲一| 成人h动漫精品| 国产精品白丝av| 成人国产一区二区三区精品| 波波电影院一区二区三区| 99久久精品免费观看| 色狠狠综合天天综合综合| 在线国产电影不卡| 在线播放91灌醉迷j高跟美女 | 国产成人久久精品77777最新版本| 夫妻av一区二区| 日本韩国精品在线| 欧美一级视频精品观看| 久久综合九色综合97婷婷| 国产精品久久久久久久久免费丝袜 | 国产日产欧美一区| 中文字幕一区二区三| 丝袜脚交一区二区| 国产在线精品一区在线观看麻豆| 成人黄色综合网站| 欧美三级午夜理伦三级中视频| 日韩视频永久免费| 欧美国产禁国产网站cc| 亚洲成a人v欧美综合天堂 | 国产精品久久久久三级| 一区二区在线观看视频| 狠狠色综合色综合网络| 色综合久久久网| 2023国产精华国产精品| 亚洲在线观看免费| 国产99久久久久久免费看农村| 在线欧美日韩国产| 久久久久久电影| 日日摸夜夜添夜夜添亚洲女人| 国产成人在线免费观看| 7777精品伊人久久久大香线蕉超级流畅 | 日本在线不卡视频一二三区|