コード例 #1
0
ファイル: net_tcp.c プロジェクト: Danfx/opensips
/* creates a new tcp connection structure and informs the TCP Main on that
 * a +1 ref is set for the new conn !
 * IMPORTANT - the function assumes you want to create a new TCP conn as
 * a result of a connect operation - the conn will be set as connect !!
 * Accepted connection are triggered internally only */
struct tcp_connection* tcp_conn_create(int sock, union sockaddr_union* su,
											struct socket_info* si, int state)
{
	struct tcp_connection *c;

	/* create the connection structure */
	c = tcp_conn_new(sock, su, si, state);
	if (c==NULL)
		return NULL;

	return (tcp_conn_send(c) == 0 ? c : NULL);
}
コード例 #2
0
ファイル: ucall.c プロジェクト: jvesely/helenos
/** OPEN user call
 *
 * @param epp		Endpoint pair
 * @param acpass	Active/passive
 * @param oflags	Open flags
 * @param conn		Connection
 *
 * Unlike in the spec we allow specifying the local address. This means
 * the implementation does not need to magically guess it, especially
 * considering there can be more than one local address.
 *
 * XXX We should be able to call active open on an existing listening
 * connection.
 * XXX We should be able to get connection structure immediately, before
 * establishment.
 */
tcp_error_t tcp_uc_open(inet_ep2_t *epp, acpass_t acpass,
    tcp_open_flags_t oflags, tcp_conn_t **conn)
{
	tcp_conn_t *nconn;
	int rc;

	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open(%p, %s, %s, %p)",
	    epp, acpass == ap_active ? "active" : "passive",
	    oflags == tcp_open_nonblock ? "nonblock" : "none", conn);

	nconn = tcp_conn_new(epp);
	rc = tcp_conn_add(nconn);
	if (rc != EOK) {
		tcp_conn_delete(nconn);
		return TCP_EEXISTS;
	}

	tcp_conn_lock(nconn);

	if (acpass == ap_active) {
		/* Synchronize (initiate) connection */
		tcp_conn_sync(nconn);
	}

	if (oflags == tcp_open_nonblock) {
		tcp_conn_unlock(nconn);
		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open -> %p", nconn);
		*conn = nconn;
		return TCP_EOK;
	}

	/* Wait for connection to be established or reset */
	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open: Wait for connection.");
	while (nconn->cstate == st_listen ||
	    nconn->cstate == st_syn_sent ||
	    nconn->cstate == st_syn_received) {
		fibril_condvar_wait(&nconn->cstate_cv, &nconn->lock);
	}

	if (nconn->cstate != st_established) {
		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open: Connection was reset.");
		assert(nconn->cstate == st_closed);
		tcp_conn_unlock(nconn);
		return TCP_ERESET;
	}

	tcp_conn_unlock(nconn);
	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open: Connection was established.");

	*conn = nconn;
	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open -> %p", nconn);
	return TCP_EOK;
}
コード例 #3
0
ファイル: proto_ws.c プロジェクト: GeorgeShaw/opensips
static struct tcp_connection* ws_sync_connect(struct socket_info* send_sock,
		union sockaddr_union* server)
{
	int s;
	union sockaddr_union my_name;
	socklen_t my_name_len;
	struct tcp_connection* con;

	s=socket(AF2PF(server->s.sa_family), SOCK_STREAM, 0);
	if (s==-1){
		LM_ERR("socket: (%d) %s\n", errno, strerror(errno));
		goto error;
	}
	if (tcp_init_sock_opt(s)<0){
		LM_ERR("tcp_init_sock_opt failed\n");
		goto error;
	}
	my_name_len = sockaddru_len(send_sock->su);
	memcpy( &my_name, &send_sock->su, my_name_len);
	su_setport( &my_name, 0);
	if (bind(s, &my_name.s, my_name_len )!=0) {
		LM_ERR("bind failed (%d) %s\n", errno,strerror(errno));
		goto error;
	}

	if (tcp_connect_blocking(s, &server->s, sockaddru_len(*server))<0){
		LM_ERR("tcp_blocking_connect failed\n");
		goto error;
	}
	con=tcp_conn_new(s, server, send_sock, S_CONN_OK);
	if (con==NULL){
		LM_ERR("tcp_conn_create failed, closing the socket\n");
		goto error;
	}
	/* it is safe to move this here and clear it after we complete the
	 * handshake, just before sending the fd to main */
	con->fd = s;
	return con;
error:
	/* close the opened socket */
	if (s!=-1) close(s);
	return 0;
}