Ejemplo n.º 1
0
static struct tcp_sock *tcp_listen_child_sock(struct tcp_sock *tsk,
						struct tcp_segment *seg)
{
	struct sock *newsk = tcp_alloc_sock(tsk->sk.protocol);
	struct tcp_sock *newtsk = tcpsk(newsk);
	tcp_set_state(newtsk, TCP_SYN_RECV);
	newsk->sk_saddr = seg->iphdr->ip_dst;
	newsk->sk_daddr = seg->iphdr->ip_src;
	newsk->sk_sport = seg->tcphdr->dst;
	newsk->sk_dport = seg->tcphdr->src;
	/* add to establish hash table for third ACK */
	if (tcp_hash(&newtsk->sk) < 0) {
		free(newsk);
		return NULL;
	}
	/*
	 * Why to get parent reference?
	 * To avoid parent accidental release.
	 * e.g: Parent is interrupted by user
	 *      when child is pending in three-way handshake.
	 */
	newtsk->parent = get_tcp_sock(tsk);
	/* FIXME: add limit to listen queue */
	list_add(&newtsk->list, &tsk->listen_queue);
	/* reference for being listed into parent queue */
	return get_tcp_sock(newtsk);
}
Ejemplo n.º 2
0
static void *bridge_channel_media(void *channel_data)
{
    unsigned char readframe[MEDIA_BUFFER_SIZE];
    unsigned char writeframe[MEDIA_BUFFER_SIZE];
    char trace_file_name[255];
    char *trace_prefix = NULL;
    wanpipe_tdm_api_t tdm_api;
    sbridge_chan_t *chan = channel_data;
    sangoma_pri_t *spri = &chan->span->spri;
    int32_t channo = chan->channo;

    memset(readframe, 0, sizeof(readframe));
    memset(writeframe, 0, sizeof(writeframe));

    /* need to disable cancellation while registering the cleanup handler
     * if we get cancelled before registering, no harm done
     * once the cleanup handler gets registered, it does not matter
     * at which point of this thread we get cancelled, the cleanup routine
     * will take care of closing sockets or any other resource we eventually allocate
     * */
    if (!sbridge_thread_setcancelstate(SBRIDGE_THREAD_CANCEL_DISABLE, NULL)) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Failed to disable thread cancellation in chanel %d\n", channo);
        sbridge_thread_exit(NULL);
    }
    if (!sbridge_thread_setcanceltype(SBRIDGE_THREAD_CANCEL_DEFERRED, NULL)) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Failed to set deferred cancel type in chanel %d\n", channo);
        sbridge_thread_exit(NULL);
    }

    /* just grab the lock to start once the thread that launched us is done using the channel
     * channel manipulations in this routine do not require the channel lock because the signaling
     * thread does not access the channel once the media thread is launched
     * */
    sbridge_mutex_lock(&chan->lock);
    chan->running = SBRIDGE_TRUE;
    sbridge_mutex_unlock(&chan->lock);

    /* register the cleanup handler */
    sbridge_thread_cleanup_push(clean_thread_data, chan);

    /* restore the cancellation state */
    sbridge_thread_setcancelstate(SBRIDGE_THREAD_CANCEL_ENABLE, NULL);

    /* open sangoma media channel */
    if ((chan->sangoma_sock = sangoma_open_tdmapi_span_chan(spri->span, channo)) < 0) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Failed to open TDM API descriptor for sangoma channel %d\n", channo);
        sbridge_thread_exit(NULL);
    }

    if (!get_tcp_sock(chan)) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Failed to get TCP socket for channel %d\n", channo);
        sbridge_thread_exit(NULL);
    }

    /* open the traces */
    trace_prefix = chan->span->config->trace_prefix;
    if (strlen(trace_prefix)) {
        CHAN_MEDIA_TRACE_OPEN(trace_raw_in);
        CHAN_MEDIA_TRACE_OPEN(trace_raw_out);
    }

    /* set the channel read period */
    if (sangoma_tdm_set_usr_period(chan->sangoma_sock, &tdm_api, SBRIDGE_MEDIA_PERIOD) < 0) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Failed to set sangoma channel read period to %d\n", SBRIDGE_MEDIA_PERIOD);
        sbridge_thread_exit(NULL);
    }

    /* everything will be passed thru as received, WP_NONE */
    if ((sangoma_tdm_set_codec(chan->sangoma_sock, &tdm_api, WP_NONE)) < 0) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Failed to set native driver codec for sangoma channel %d\n", channo);
        sbridge_thread_exit(NULL);
    }

    chan->mtu = sangoma_tdm_get_usr_mtu_mru(chan->sangoma_sock, &tdm_api);
    if (chan->mtu != SBRIDGE_ALAW_MTU) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Unexpected MTU of size %d, cannot handle media\n", chan->mtu);
        sbridge_thread_exit(NULL);
    }

    sbridge_log(SBRIDGE_LOG_NOTICE, "Sangoma socket MTU is %d\n", chan->mtu);

    /* run the proper application depending on the chan mode */
    chan->app_func(chan);

    /* done, let's clean up our mess and notify the signaling thread */
    sbridge_log(SBRIDGE_LOG_NOTICE, "Media thread for channel %d completed application execution\n", channo);

    if (!sbridge_thread_setcancelstate(SBRIDGE_THREAD_CANCEL_DISABLE, NULL)) {
        sbridge_log(SBRIDGE_LOG_ERROR, "Failed to disable thread cancellation when terminating media thread for channel %d\n",
                    channo);
        sbridge_thread_exit(NULL);
    }

    /* this calls the cleanup handler to free resources */
    sbridge_thread_cleanup_pop(SBRIDGE_THREAD_CLEANUP_EXECUTE);

    sbridge_thread_exit(NULL);
    return NULL;
}