示例#1
0
enum proto_accept_error
proto_accept_connection(int listener_fd, int *read_fd, int *write_fd,
			const char **name)
{
    int timeout = server_int_option("name_lookup_timeout", 5);
    int fd;
    struct sockaddr_in *addr = (struct sockaddr_in *) call->addr.buf;
    static Stream *s = 0;

    if (!s)
	s = new_stream(100);

    fd = t_open((void *) "/dev/tcp", O_RDWR, 0);
    if (fd < 0) {
	if (t_errno == TSYSERR && errno == EMFILE)
	    return PA_FULL;
	else {
	    log_ti_error("Opening endpoint for new connection");
	    return PA_OTHER;
	}
    }
    if (t_bind(fd, 0, 0) < 0) {
	log_ti_error("Binding endpoint for new connection");
	t_close(fd);
	return PA_OTHER;
    }
    if (t_listen(listener_fd, call) < 0) {
	log_ti_error("Accepting new network connection");
	t_close(fd);
	return PA_OTHER;
    }
    if (t_accept(listener_fd, fd, call) < 0) {
	log_ti_error("Accepting new network connection");
	t_close(fd);
	return PA_OTHER;
    }
    if (!set_rw_able(fd)) {
	t_close(fd);
	return PA_OTHER;
    }
    *read_fd = *write_fd = fd;
    stream_printf(s, "%s, port %d",
		  lookup_name_from_addr(addr, timeout),
		  (int) ntohs(addr->sin_port));
    *name = reset_stream(s);
    return PA_OKAY;
}
示例#2
0
/* FUNCTION: bsd_accept()
 *
 * Accept a connection on a socket
 *
 * PARAM1: s; IN - socket descriptor for the listening socket
 * PARAM2: addr; OUT - ptr to buffer for return of accepted peer's address;
 *               may be NULL if return of address is not requested
 * PARAM3: addrlen; IN/OUT - ptr to int; on entry, specifies the length
 *                  in bytes of addr; on successful return, specifies the
 *                  length of the returned address; may be NULL if 
 *                  addr is also NULL
 * RETURNS: A socket descriptor if successful, -1 if an error occurred.  
 *          The error is available via bsd_errno(s).
 */
BSD_SOCKET
bsd_accept(BSD_SOCKET s,
           struct sockaddr * addr, int * addrlen)
{
   struct socket * so;
   struct sockaddr laddr;
   long lret;

   so = LONG2SO(s);
   SOC_CHECK(so);

   /* if we were given a buffer for the peer's address, also get the
    * buffer's length 
    */
   if (addr != NULL)
   {
      if (addrlen == 0)
      {
         so->so_error = EFAULT;
         return -1;
      }
   }

   lret = t_accept(s, &laddr, addrlen);

   /* if we were successful, and we were given a buffer for the peer's
    * address: copy the peer's address back into the buffer, but limit
    * the copy to the lesser of the buffer's length and sizeof(struct
    * sockaddr_in), which is all that t_accept() can return as a peer
    * address.  
    */
   if ((lret != -1) && (addr != NULL))
   {
      if (*addrlen > sizeof(struct sockaddr_in))
         *addrlen = sizeof(struct sockaddr_in);
      MEMCPY(addr, &laddr, *addrlen);
   }

   return lret;
}
示例#3
0
文件: serwer.c 项目: batas2/UMK
int accept_client(int fd, struct t_call *call)
{
	int sd;

	if ((sd = t_open(DEV_XTI, O_RDWR, NULL)) < 0)
		error("serwer->accept_client->t_open", fd, sd);

	if (t_bind(sd, NULL, NULL) < 0)
		error("serwer->accept_client->t_bind", fd, sd);

	if (t_accept(fd, sd, call) < 0) {
		if (t_errno == TLOOK) {
			if (t_rcvdis(fd, NULL) < 0)
				error("serwer->accept_client->t_rcvdis", fd, sd);

			if (t_close(sd) < 0)
				error("serwer->accept_client->t_close", fd, sd);

			return -1;
		}
		error("t_accept failed", fd, sd);
	}
	return(sd);
}
示例#4
0
文件: tlx.c 项目: alhazred/onarm
/*
 * This call attempts to t_accept() an incoming/pending TLI connection.
 * If it is thwarted by a TLOOK, it is deferred and whatever is on the
 * file descriptor, removed after a t_look. (Incoming connect indications
 * get queued for later processing and disconnect indications remove a
 * a queued connection request if a match found).
 * Returns -1 on failure, else 0.
 */
int
tlx_accept(const char *fmri, tlx_info_t *tlx_info,
    struct sockaddr_storage *remote_addr)
{
	tlx_conn_ind_t	*conind;
	struct t_call	*call;
	int		fd;
	int		listen_fd = tlx_info->pr_info.listen_fd;

	debug_msg("Entering tlx_accept: instance: %s", fmri);

	if ((fd = t_open(tlx_info->dev_name, O_RDWR, NULL)) == -1) {
		error_msg("t_open: %s", t_strerror(t_errno));
		return (-1);
	}

	if (tlx_info->pr_info.v6only) {
		int	on = 1;

		/* restrict to IPv6 communications only */
		if (tlx_setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on,
		    sizeof (on)) == -1) {
			(void) t_close(fd);
			return (-1);
		}
	}

	if (t_bind(fd, NULL, NULL) == -1) {
		error_msg("t_bind: %s", t_strerror(t_errno));
		(void) t_close(fd);
		return (-1);
	}

	/*
	 * Get the next connection indication - first try the pending
	 * queue, then, if none there, get a new one from the file descriptor.
	 */
	if ((conind = uu_list_first(tlx_info->conn_ind_queue)) != NULL) {
		debug_msg("taking con off queue");
		call = conind->call;
	} else if ((call = get_new_conind(listen_fd)) == NULL) {
		(void) t_close(fd);
		return (-1);
	}

	/*
	 * Accept the connection indication on the newly created endpoint.
	 * If we fail, and it's the result of a tlook, queue the indication
	 * if it isn't already, and go and process the t_look.
	 */
	if (t_accept(listen_fd, fd, call) == -1) {
		if (t_errno == TLOOK) {
			if (uu_list_first(tlx_info->conn_ind_queue) == NULL) {
				/*
				 * We are first one to have to defer accepting
				 * and start the pending connections list.
				 */
				if (queue_conind(tlx_info->conn_ind_queue,
				    call) == -1) {
					error_msg(gettext(
					    "Failed to queue connection "
					    "indication for instance %s"),
					    fmri);
					(void) t_free((char *)call, T_CALL);
					return (-1);
				}
			}
			(void) process_tlook(fmri, tlx_info);
		} else {		  /* non-TLOOK accept failure */
			error_msg("%s: %s", "t_accept failed",
			    t_strerror(t_errno));
			/*
			 * If we were accepting a queued connection, dequeue
			 * it.
			 */
			if (uu_list_first(tlx_info->conn_ind_queue) != NULL)
				(void) dequeue_conind(tlx_info->conn_ind_queue);
			(void) t_free((char *)call, T_CALL);
		}

		(void) t_close(fd);
		return (-1);
	}

	/* Copy remote address into address parameter */
	(void) memcpy(remote_addr, call->addr.buf,
	    MIN(call->addr.len, sizeof (*remote_addr)));

	/* If we were accepting a queued connection, dequeue it. */
	if (uu_list_first(tlx_info->conn_ind_queue) != NULL)
		(void) dequeue_conind(tlx_info->conn_ind_queue);
	(void) t_free((char *)call, T_CALL);

	return (fd);
}
示例#5
0
static XtransConnInfo
TRANS(TLIAccept)(XtransConnInfo ciptr, int *status)

{
    struct t_call	*call;
    XtransConnInfo	newciptr;
    int	i;

    prmsg(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd);

    if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
    {
	prmsg(1, "TLIAccept() failed to allocate a t_call\n");
	*status = TRANS_ACCEPT_BAD_MALLOC;
	return NULL;
    }

    if( t_listen(ciptr->fd,call) < 0 )
    {
	extern char *t_errlist[];
	extern int t_errno;
	prmsg(1, "TLIAccept() t_listen() failed\n");
	prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]);
	t_free((char *)call,T_CALL);
	*status = TRANS_ACCEPT_MISC_ERROR;
	return NULL;
    }

    /*
     * Now we need to set up the new endpoint for the incoming connection.
     */

    i=ciptr->index; /* Makes the next line more readable */

    if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
    {
	prmsg(1, "TLIAccept() failed to open a new endpoint\n");
	t_free((char *)call,T_CALL);
	*status = TRANS_ACCEPT_MISC_ERROR;
	return NULL;
    }

    if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 )
    {
	prmsg(1,
	      "TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n",
	      errno);
	t_free((char *)call,T_CALL);
	t_close(newciptr->fd);
	free(newciptr);
	*status = TRANS_ACCEPT_MISC_ERROR;
	return NULL;
    }


    if( t_accept(ciptr->fd,newciptr->fd,call) < 0 )
    {
	extern char *t_errlist[];
	extern int t_errno;
	prmsg(1, "TLIAccept() t_accept() failed\n");
	prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]);
	if( t_errno == TLOOK )
	{
	    int evtype = t_look(ciptr->fd);
	    prmsg(1, "TLIAccept() t_look() returned %d\n", evtype);
	    switch( evtype )
	    {
		case T_DISCONNECT:
		    if( t_rcvdis(ciptr->fd, NULL) < 0 )
		    {
			prmsg(1, "TLIAccept() t_rcvdis() failed\n");
			prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]);
		    }
		    break;
		default:
		    break;
	    }
	}
	t_free((char *)call,T_CALL);
	t_close(newciptr->fd);
	free(newciptr);
	*status = TRANS_ACCEPT_FAILED;
	return NULL;
    }

    t_free((char *)call,T_CALL);

    if( TRANS(TLIGetAddr)(newciptr) < 0 )
    {
	prmsg(1,
	      "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
	      errno);
	t_close(newciptr->fd);
	free(newciptr);
	*status = TRANS_ACCEPT_MISC_ERROR;
	return NULL;
    }

    if( TRANS(TLIGetPeerAddr)(newciptr) < 0 )
    {
	prmsg(1,
	      "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
	      errno);
	t_close(newciptr->fd);
	free(newciptr->addr);
	free(newciptr);
	*status = TRANS_ACCEPT_MISC_ERROR;
	return NULL;
    }

    if( ioctl(newciptr->fd, I_POP,"timod") < 0 )
    {
	prmsg(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n",
	      errno);
	t_close(newciptr->fd);
	free(newciptr->addr);
	free(newciptr);
	*status = TRANS_ACCEPT_MISC_ERROR;
	return NULL;
    }

    if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 )
    {
	prmsg(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
	      errno);
	t_close(newciptr->fd);
	free(newciptr->addr);
	free(newciptr);
	*status = TRANS_ACCEPT_MISC_ERROR;
	return NULL;
    }

    *status = 0;

    return newciptr;
}
示例#6
0
/*
 ****************************************************************
 *	Aguarda pedidos de conexão (servidor)			*
 ****************************************************************
 */
int
tcp_listen (int fd, char *name)
{
	T_CALL		call;
	T_BIND		bind;
	INADDR		client_addr, addr[2];
	int		newfd;
	char		*cp;

	/*
	 *	Preenche a estrutura T_CALL: só o membro addr é relevante.
	 */
	FILL_NETBUF (call.addr,  &client_addr, sizeof (client_addr));
	FILL_NETBUF (call.opt,   NULL,         0);
	FILL_NETBUF (call.udata, NULL,         0);

	/*
	 *	Espera chegar um pedido de conexão.
	 */
	if (t_listen (fd, &call) < 0)
		return (-1);

	/*
	 *	Abre outro "endpoint".
	 */
	if ((newfd = t_open (tcpdevname, O_RDWR, (T_INFO *)NULL)) < 0)
		return (-1);

	/*
	 *	Preenche a estrutura T_BIND.
	 */
	if (client_addr.a_addr == LOCAL_IP_ADDR)
	{	/*
		 *	A conexão é local: deixa o kernel gerar outro port.
		 */
		bind.addr.len    = 0;
		bind.addr.buf    = addr;
		bind.addr.maxlen = sizeof (INADDR);
	}
	else
	{	/*
		 *	A conexão é remota: respeita o port do "t_listen".
		 */
		FILL_INADDR (addr[0], 0, listen_port);
		FILL_INADDR (addr[1], client_addr.a_addr, client_addr.a_port);
		FILL_NETBUF (bind.addr, addr, sizeof (addr));
	}

	bind.qlen = 0;		/* Não vamos dar "t_listen" nesta conexão */

	if (t_bind (newfd, &bind, (T_BIND *)NULL) < 0)
		goto bad;

	if (set_param (newfd) < 0)
		goto bad;

	/*
	 *	Aceita a conexão no novo "endpoint".
	 */
	if (t_accept (fd, newfd, &call) < 0)
		goto bad;

	if
	(	name != NOSTR &&
		(cp = t_addr_to_node (fd, client_addr.a_addr)) != NOSTR
	)
		strcpy (name, cp);

	return (newfd);

bad:	t_close (newfd);
	return (-1);

}	/* end tcp_listen */
示例#7
0
void tcp_ipv6_poll()
{
	int indx = 0;
	int freeSlot = 0;
	for(; indx<MAX_SOCK_NO; indx++)
		if(g_sockets[indx].indxToListen == -1)
		{
			int sa_size = sizeof(struct sockaddr_in6);
			struct sockaddr_in6   stFrom;

			SOCKTYPE sock = t_accept(g_sockets[indx].sock,(struct sockaddr*)&stFrom, &sa_size);

			//C_NLOG_INFO("Iniche:tcp_ipv6_poll: 0");

			if(sock <= 0)
				continue;

			//C_NLOG_INFO("Iniche:tcp_ipv6_poll: 1");
			//C_NLOG_INFO("Iniche:tcp_ipv6_poll: 2");

			int iTmp = 1;
			int e = t_setsockopt(sock, SOL_SOCKET, SO_NONBLOCK, (void *)&iTmp, sizeof(iTmp));
			if (e == SOCKET_ERROR)
			{
				e = t_errno(sock);
				t_socketclose(sock);
				C_NLOG_ERR("Iniche:tcp_ipv6_pool: t_setsockopt() SO_NONBLOCK failed, Err: %d", e);
				continue;
			}
			iTmp = INICHE_TCP_RCV_MAX_BUFF_LEN;
			e = t_setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&iTmp, sizeof(iTmp));
			if (e == SOCKET_ERROR)
			{
				e = t_errno(sock);
				t_socketclose(sock);
				C_NLOG_ERR("Iniche:tcp_ipv6_pool: t_setsockopt() SO_RCVBUF failed, Err: %d", e);
				continue;
			}

			int isSett = 0;
			for(; freeSlot < MAX_SOCK_NO; freeSlot++)
			{
				if(g_sockets[freeSlot].sock == INVALID_SOCKET)
				{
					//callback
					g_sockets[freeSlot].sock = sock;
					g_sockets[freeSlot].indxToListen = indx;
					(gFunctions->m_pfnAccept)((void *)(g_sockets+freeSlot));
					//C_NLOG_INFO("Iniche:tcp_ipv6_poll: HCONN accepted = %X, index=%d",sock,freeSlot);
					isSett = 1;

					break;
				}
			}
			//if no free slot founded, then break
			if(isSett == 0)
			{
				C_NLOG_ERR("Iniche:tcp_ipv6_poll: No free slot for creating soket !");
				t_socketclose(sock);
				break;
			}

			//C_NLOG_INFO("Iniche:tcp_ipv6_poll: 4");
		}


	unsigned char buff[INICHE_TCP_RCV_MAX_BUFF_LEN];

	int j = 0;
	for(; j < MAX_SOCK_NO; j++)
	{	if(g_sockets[j].indxToListen != -1)
		{
			if(g_sockets[j].sock == INVALID_SOCKET)
			{
				continue;
			}

			int len = t_recv(g_sockets[j].sock, (char*)buff, INICHE_TCP_RCV_MAX_BUFF_LEN, 0);
			if(len > 0)
			{
				//C_NLOG_INFO("Iniche:tcp_ipv6_poll: 6 len = %d, buff=%s", len, (char*)buff);
				(gFunctions->m_pfnRecv)((void*)(g_sockets+j),buff,len);
			}
		}
	}
}