示例#1
0
/* For the pinentry to work correctly with SSH, we need to record the process ID
 * of the process communicating with the agent. That way we can get more
 * information about the PTS/PTY/TTY the user is on and also know whether a
 * DISPLAY is set for that process, because we will connect the pinentry's TTY
 * to the TTY of the process on the other end of the socket.
 */
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
    int retval;

    static int (*_accept)(int, struct sockaddr *, socklen_t *) = NULL;
    if (_accept == NULL)
        _accept = dlsym(RTLD_NEXT, "accept");

    retval = _accept(sockfd, addr, addrlen);

    last_pid = 0;

#ifdef SUPERVISOR_SUPPORT
    if (ssh_fd == 0) gather_sd_fds();
#endif

    if (retval != -1 && ssh_fd != 0 && sockfd == ssh_fd) {
        pid_t client_pid = get_socket_pid(retval);
        if (client_pid == -1) {
            close(retval);
            return -1;
        }
        last_pid = client_pid;
        fprintf(stderr, "Socket endpoint PID for accepted socket %d is %d.\n",
                retval, client_pid);
    }

    return retval;
}
 // TODO accept an IP address to bind to
 AsyncMessageServer( const MessageServer::Options& opts , MessageHandler * handler )
     : _port( opts.port )
     , _handler(handler)
     , _endpoint( tcp::v4() , opts.port )
     , _acceptor( _ioservice , _endpoint ) {
     _accept();
 }
 AsyncMessageServer( int port , MessageHandler * handler )
     : MessageServer( port , handler )
     , _endpoint( tcp::v4() , port )
     , _acceptor( _ioservice , _endpoint )
 {
     _accept();
 }
示例#4
0
void on_set(int sfd){
	int client_sfd = _accept(sfd);
	int index = get_service_index(sfd);
	printf("Client requested for service %s\n", services[index].name);
	// if (services[index].started == 0){
	// 	int pid = fork();
	// 	if (pid == 0){
	// 		char *cap = (char *)malloc(sizeof(char)*10);
	// 		sprintf(cap, "%d", services[index].capacity);
	// 		if (index == 0){
	// 			execl(services[index].name, services[index].name, services[index].name, cap,"server", services[index+1].name,(char*)0);

	// 		}
	// 		else if (index == MAX_SERVICES -1){
	// 			execl(services[index].name, services[index].name, services[index].name, cap,services[index-1].name, "server",(char*)0);

	// 		}
	// 		else{
	// 			execl(services[index].name, services[index].name, services[index].name, cap,services[index-1].name, services[index+1].name,(char*)0);

	// 		}
	// 	}
	// 	else{
	// 		services[index].unsfd = _accept(services[index].usfd);
	// 		services[index].started = 1;
	// 	}
		
	// }
	send_fd(services[index].usfd, client_sfd); // sending the accepted client sfd to the service.
	// printf("Sent the fd\n");
}
示例#5
0
static void process_accept(kn_socket *s){
    int fd;
    kn_sockaddr remote;
    for(;;)
    {
    	fd = _accept(s,&remote);
    	if(fd < 0)
    		break;
    	else{
		   handle_t h = new_stream_socket(fd,s->domain);	
		   ((kn_socket*)h)->addr_local = s->addr_local;
		   ((kn_socket*)h)->addr_remote = remote;
		   if(((kn_stream_socket*)s)->ctx){
		   	((kn_stream_socket*)h)->ssl = SSL_new(((kn_stream_socket*)s)->ctx);
		   	SSL_set_fd(((kn_stream_socket*)h)->ssl, fd);
        			if (SSL_accept(((kn_stream_socket*)h)->ssl) == -1) {
            				printf("SSL_accept error\n");
            				stream_socket_close(h);
            				continue;
        			}
		   }
		   h->status = SOCKET_ESTABLISH;
		   ((kn_socket*)s)->callback(h,s,0,0);
    	}      
    }
}
示例#6
0
    Socket* TLSSocket::accept() {
        string inf;
        Fd connFd = _accept(inf);
        if (connFd == -1)
            throw SocketExcept("accept failed");

        return new TLSSocket(connFd, *this, inf); 
    }
示例#7
0
文件: tcp.cpp 项目: tycho/sheepshaver
static void tcp_accept_callback( const int lst )
{
  D(bug("[%d] tcp_accept_callback()\r\n", lst));

	struct sockaddr_in to;
	memset( &to, 0, sizeof(to) );
	to.sin_family = AF_INET;
	int tolen = sizeof(to);

	SOCKET s = _accept( l_sockets[lst].s, (struct sockaddr *)&to, &tolen );
	if( s == INVALID_SOCKET ) {
		D(bug("[%d] connection not accepted, error code %d\r\n", lst, _WSAGetLastError()));
	} else {
		_WSAEventSelect( s, 0, 0 );

		uint16 src_port = l_sockets[lst].port;
		uint16 dest_port = ntohs(to.sin_port);
		uint32 ip_dest = ntohl(to.sin_addr.s_addr);

	  D(bug("[%d] connection accepted, local port:%d, remote %s:%d\r\n", lst, src_port, _inet_ntoa(to.sin_addr), dest_port));

		if( l_sockets[lst].ip != 0 && l_sockets[lst].ip != ip_dest ) {
			_closesocket( s );
		  D(bug("[%d] authorization failure. connection closed.\r\n", lst ));
		} else {
			int t = alloc_new_socket( src_port, dest_port, ip_dest );
			if( t < 0 ) {
				D(bug("<%d> out of slot space, connection dropped\r\n", t ));
				free_socket(t);
			} else {
				sockets[t].s = s;
				sockets[t].state = LISTEN;
				sockets[t].src_port = src_port;
				sockets[t].dest_port = dest_port;
				sockets[t].ip_src = macos_ip_address;
				sockets[t].ip_dest = ip_dest;

				sockets[t].seq_out = 0x00000001;
				sockets[t].seq_in = 0; // not known yet
				sockets[t].mac_ack = sockets[t].seq_out; // zero out pending bytes

				tcp_reply( SYN, t );
				sockets[t].seq_out++;
				sockets[t].state = SYN_SENT;
				sockets[t].time_wait = GetTickCount() + SYN_FLOOD_PROTECTION_TIMEOUT;
				D(bug("<%d> Connect: LISTEN -> SYN_SENT\r\n", t));

				_WSAResetEvent( sockets[t].ev );
				if( SOCKET_ERROR == _WSAEventSelect( sockets[t].s, sockets[t].ev, FD_CLOSE ) ) {
					D(bug("<%d> WSAEventSelect() failed with error code %d\r\n", t, _WSAGetLastError()));
				}

				// No data from the remote host is needed until the connection is established.
				// So don't initiate read yet.
			}
		}
	}
}
 void handleAccept( shared_ptr<MessageServerSession> session , 
                    const boost::system::error_code& error ){
     if ( error ){
         cout << "handleAccept error!" << endl;
         return;
     }
     session->start();
     _accept();
 }
示例#9
0
void _callback(int fd, short which, void* v)
{
    (void)which;
    int new_fd = _accept(fd);
    if (new_fd != -1)
    {
        AcceptService* service = (AcceptService*)v;
        service->run(new_fd);
    }
}
示例#10
0
PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
                        PRIntervalTime timeout)
{
    PRInt32 rv;

    _MD_BLOCK_CLOCK_INTERRUPTS();
    rv = _accept(osfd,addr,addrlen);
    _MD_UNBLOCK_CLOCK_INTERRUPTS();
    return(rv);
}
示例#11
0
int
accept(int s, struct sockaddr *addr, int *addrlen)
{
	int	a;
	if ((a = _accept(s, addr, addrlen)) == -1) {
		if (errno == N_AGAIN)
			errno = EWOULDBLOCK;
		else	
			maperror(errno);
	}
	return (a);
}
示例#12
0
文件: FTPServer.c 项目: agb861/ddd
/*********************************************************************
*
*       _Accept
*
*  Function description
*    This function is called from the FTP server module if the client
*    uses passive FTP. It sets the command socket to non-blocking before
*    accept() will be called. This guarantees that the FTP server always
*    returns even if the connection to the client gets lost while
*    accept() waits for a connection. The timeout is set to 10 seconds.
*
*  Return value
*    0    O.K.
*   -1    Error
*/
static int _Accept(FTPS_SOCKET CtrlSocket, FTPS_SOCKET * pSocket) {
  int Socket;
  int DataSock;
  int SoError;
  int t0;
  int t;
  struct sockaddr Addr;
  int AddrSize;
  int Opt;

  AddrSize = sizeof(Addr);
  Socket   = *(int*)pSocket;
  //
  // Set command socket non-blocking
  //
  Opt      = 1;
  setsockopt(Socket, SOL_SOCKET, SO_NONBLOCK, &Opt, sizeof(Opt));
  t0 = IP_OS_GetTime32();
  do {
    DataSock = _accept(Socket, &Addr, &AddrSize);
    if (DataSock != SOCKET_ERROR) {
      //
      // Set command socket blocking
      //
      Opt = 0;
      setsockopt(Socket, SOL_SOCKET, SO_NONBLOCK, &Opt, sizeof(Opt));
      //
      // Set data socket blocking. The data socket inherits the blocking
      // mode from the socket that was used as parameter for accept().
      // Therefore, we have to set it blocking after creation.
      // SO_KEEPALIVE is required to quarantee that the socket will be
      // closed even if the client has lost the connection to server
      // before he closed the connection.
      //
      setsockopt(DataSock, SOL_SOCKET, SO_NONBLOCK, &Opt, sizeof(Opt));
      Opt=1;
      setsockopt(DataSock, SOL_SOCKET, SO_KEEPALIVE, &Opt, sizeof(Opt));
      *pSocket = (FTPS_SOCKET)DataSock;
      return 0;                  // Successfully connected
    }
    getsockopt(Socket, SOL_SOCKET, SO_ERROR, &SoError, sizeof(SoError));
    if (SoError != EWOULDBLOCK) {
      return SOCKET_ERROR;       // Not in progress and not successful, error...
    }
    t = IP_OS_GetTime32() - t0;
    if (t >= 10000) {
      return SOCKET_ERROR;
    }
    OS_Delay(1);                 // Give lower prior tasks some time
  } while (1);
}
示例#13
0
int socket_accept(int fd, char *ip, size_t ip_len, int *port)
{
    int s;
    struct sockaddr_storage sa;
    socklen_t salen = sizeof(sa);

    s = _accept(fd, (struct sockaddr*)&sa, &salen);
    if (s == CORVUS_AGAIN || s == CORVUS_ERR) return s;

    struct sockaddr_in *addr = (struct sockaddr_in*)&sa;
    if (ip) inet_ntop(AF_INET, (void*)&(addr->sin_addr), ip, ip_len);
    if (port) *port = ntohs(addr->sin_port);
    return s;
}
示例#14
0
void triviaServer::serve(struct addrinfo* a)
{
	bindAndListen(a);
	std::thread(&triviaServer::handleRecievedMessages, this).detach();
	while (true)
	{
		try
		{
			_accept(listenSocket);
		}
		catch (std::exception &e)
		{
			std::cout << e.what() << std::endl;
		}
	}
}
示例#15
0
static void process_accept(chk_handle *h,int32_t events) {
	int32_t 	 fd;
	int32_t      ret;
    chk_sockaddr addr;
    chk_acceptor *acceptor = cast(chk_acceptor*,h);
	if(events == CHK_EVENT_LOOPCLOSE){
		acceptor->cb(acceptor,-1,NULL,acceptor->ud,chk_error_loop_close);
		return;
	}
    do {
		ret = _accept(acceptor,&addr,&fd);
		if(ret == 0)
		   acceptor->cb(acceptor,fd,&addr,acceptor->ud,0);
		else if(ret != EAGAIN)
		   acceptor->cb(acceptor,-1,NULL,acceptor->ud,chk_error_accept);
	}while(0 == ret && chk_is_read_enable(h));	      
}
示例#16
0
void tcp_basesession::on_accept( tcp_server* p )
{
	p->increase_connection_count();
	m_isconnected = true;
	m_last_action_time = (unsigned int)time( NULL );
	m_father = p;
	m_dsv.reset();
	_accept();
	//m_send_crypt_key = rand() % 255 + 1;
	//m_recv_crypt_key = m_send_crypt_key;
	//send_message( &m_send_crypt_key, 1 );
	_read_next_message();
	m_thread_index = p->generate_thread_index();

	m_remote_ip_str = get_remote_address_string();
	m_remote_ip_ui = get_remote_address_ui();
	_record_action();
}
示例#17
0
void process_accept(socket_t s)
{
    SOCK client;
    //struct sockaddr_in ClientAddress;
    socklen_t len = sizeof(s->addr_remote);
    while(1)
    {
        client = _accept(s, (struct sockaddr*)&s->addr_remote,&len);
        if (client == INVALID_SOCK)
            break;
        else{
            socket_t _client = (socket_t)client;
            len = sizeof(_client->addr_local);
            getpeername(_client->fd,(struct sockaddr*)&_client->addr_remote,&len);
            getsockname(_client->fd,(struct sockaddr*)&_client->addr_local,&len);
            s->on_accept(client,&_client->addr_remote,s->ud);
        }
    }
}
示例#18
0
 void accept() { _accept(); }
示例#19
0
VisitorResult Server::accept( ServerVisitor& visitor ) const
{
    return _accept( this, visitor );
}
示例#20
0
VisitorResult Config::_acceptCompounds( ConfigVisitor& visitor ) const
{
    return _accept( this, visitor );
}
示例#21
0
/*ARGSUSED*/
static bool_t
rendezvous_request(SVCXPRT *xprt, struct rpc_msg *msg)
{
	int sock, flags;
	struct cf_rendezvous *r;
	struct cf_conn *cd;
	struct sockaddr_storage addr;
	socklen_t len;
	struct __rpc_sockinfo si;
	SVCXPRT *newxprt;
	fd_set cleanfds;

	assert(xprt != NULL);
	assert(msg != NULL);

	r = (struct cf_rendezvous *)xprt->xp_p1;
again:
	len = sizeof addr;
	if ((sock = _accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr,
	    &len)) < 0) {
		if (errno == EINTR)
			goto again;
		/*
		 * Clean out the most idle file descriptor when we're
		 * running out.
		 */
		if (errno == EMFILE || errno == ENFILE) {
			cleanfds = svc_fdset;
			__svc_clean_idle(&cleanfds, 0, FALSE);
			goto again;
		}
		return (FALSE);
	}
	/*
	 * make a new transporter (re-uses xprt)
	 */
	newxprt = makefd_xprt(sock, r->sendsize, r->recvsize);
	newxprt->xp_rtaddr.buf = mem_alloc(len);
	if (newxprt->xp_rtaddr.buf == NULL)
		return (FALSE);
	memcpy(newxprt->xp_rtaddr.buf, &addr, len);
	newxprt->xp_rtaddr.len = len;
#ifdef PORTMAP
	if (addr.ss_family == AF_INET || addr.ss_family == AF_LOCAL) {
		newxprt->xp_raddr = *(struct sockaddr_in *)newxprt->xp_rtaddr.buf;
		newxprt->xp_addrlen = sizeof (struct sockaddr_in);
	}
#endif				/* PORTMAP */
	if (__rpc_fd2sockinfo(sock, &si) && si.si_proto == IPPROTO_TCP) {
		len = 1;
		/* XXX fvdl - is this useful? */
		_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &len, sizeof (len));
	}

	cd = (struct cf_conn *)newxprt->xp_p1;

	cd->recvsize = r->recvsize;
	cd->sendsize = r->sendsize;
	cd->maxrec = r->maxrec;

	if (cd->maxrec != 0) {
		flags = _fcntl(sock, F_GETFL, 0);
		if (flags  == -1)
			return (FALSE);
		if (_fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
			return (FALSE);
		if (cd->recvsize > cd->maxrec)
			cd->recvsize = cd->maxrec;
		cd->nonblock = TRUE;
		__xdrrec_setnonblock(&cd->xdrs, cd->maxrec);
	} else
		cd->nonblock = FALSE;

	gettimeofday(&cd->last_recv_time, NULL);

	return (FALSE); /* there is never an rpc msg to be processed */
}
示例#22
0
static
VALUE rhe_accept(VALUE self, VALUE fileno, VALUE timeoutv, VALUE tcp, VALUE env) {
  struct sockaddr_in cliaddr;
  unsigned int len;
  char read_buf[MAX_HEADER_SIZE];
  VALUE req;
  int flag = 1;
  ssize_t rv = 0;
  ssize_t buf_len;
  ssize_t reqlen;
  int fd;
  double timeout = NUM2DBL(timeoutv);

  len = sizeof(cliaddr);
  fd = _accept(NUM2INT(fileno), (struct sockaddr *)&cliaddr, len);

  /* endif */
  if (fd < 0) {
    goto badexit;
  }

  rv = _read_timeout(fd, timeout, &read_buf[0], MAX_HEADER_SIZE);
  if ( rv <= 0 ) {
    close(fd);
    goto badexit;
  }

  if ( IMMEDIATE_P(tcp) ) {
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
    rb_hash_aset(env, remote_addr_key, rb_str_new2(inet_ntoa(cliaddr.sin_addr)));
    rb_hash_aset(env, remote_port_key, rb_String(rb_int_new(ntohs(cliaddr.sin_port))));
  }
  else {
    rb_hash_aset(env, remote_addr_key, rb_str_new("",0));
    rb_hash_aset(env, remote_port_key, rb_String(rb_int_new(0)));
  }

  buf_len = rv;
  while (1) {
    reqlen = _parse_http_request(&read_buf[0],buf_len,env);
    if ( reqlen >= 0 ) {
      break;
    }
    else if ( reqlen == -1 ) {
      /* error */
      close(fd);
      goto badexit;
    }
    if ( MAX_HEADER_SIZE - buf_len == 0 ) {
      /* too large header  */
     char* badreq;
     badreq = BAD_REQUEST;
     rv = _write_timeout(fd, timeout, badreq, sizeof(BAD_REQUEST) - 1);
     close(fd);
     goto badexit;
    }
    /* request is incomplete */
    rv = _read_timeout(fd, timeout, &read_buf[buf_len], MAX_HEADER_SIZE - buf_len);
    if ( rv <= 0 ) {
      close(fd);
      goto badexit;
    }
    buf_len += rv;
  }

  req = rb_ary_new2(3);
  rb_ary_push(req, rb_int_new(fd));
  rb_ary_push(req, rb_str_new(&read_buf[reqlen],buf_len - reqlen));
  return req;
 badexit:
  return Qnil;
}
示例#23
0
static BOOL freerdp_listener_check_fds(freerdp_listener* instance)
{
	int i;
	void* sin_addr;
	int peer_sockfd;
	freerdp_peer* client = NULL;
	int peer_addr_size;
	struct sockaddr_storage peer_addr;
	rdpListener* listener = (rdpListener*) instance->listener;
	static const BYTE localhost6_bytes[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
	BOOL peer_accepted;

	if (listener->num_sockfds < 1)
		return FALSE;

	for (i = 0; i < listener->num_sockfds; i++)
	{
		WSAResetEvent(listener->events[i]);

		peer_addr_size = sizeof(peer_addr);
		peer_sockfd = _accept(listener->sockfds[i], (struct sockaddr*) &peer_addr, &peer_addr_size);
		peer_accepted = FALSE;

		if (peer_sockfd == -1)
		{
#ifdef _WIN32
			int wsa_error = WSAGetLastError();

			/* No data available */
			if (wsa_error == WSAEWOULDBLOCK)
				continue;
#else
			if (errno == EAGAIN || errno == EWOULDBLOCK)
				continue;
#endif
			WLog_DBG(TAG, "accept");

			free(client);
			return FALSE;
		}

		client = freerdp_peer_new(peer_sockfd);
		if (!client)
		{
			closesocket((SOCKET) peer_sockfd);
			return FALSE;
		}

		sin_addr = NULL;
		if (peer_addr.ss_family == AF_INET)
		{
			sin_addr = &(((struct sockaddr_in*) &peer_addr)->sin_addr);
			if ((*(UINT32*) sin_addr) == 0x0100007f)
				client->local = TRUE;
		}
		else if (peer_addr.ss_family == AF_INET6)
		{
			sin_addr = &(((struct sockaddr_in6*) &peer_addr)->sin6_addr);
			if (memcmp(sin_addr, localhost6_bytes, 16) == 0)
				client->local = TRUE;
		}
#ifndef _WIN32
		else if (peer_addr.ss_family == AF_UNIX)
			client->local = TRUE;
#endif

		if (sin_addr)
			inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname));

		IFCALLRET(instance->PeerAccepted, peer_accepted, instance, client);

		if (!peer_accepted)
		{
			WLog_ERR(TAG, "PeerAccepted callback failed");
			closesocket((SOCKET) peer_sockfd);
			freerdp_peer_free(client);
		}
	}

	return TRUE;
}
示例#24
0
int
rcmd_af(char **ahost, int rport, const char *locuser, const char *remuser,
	const char *cmd, int *fd2p, int af)
{
	struct addrinfo hints, *res, *ai;
	struct sockaddr_storage from;
	fd_set reads;
	sigset_t oldmask, newmask;
	pid_t pid;
	int s, aport, lport, timo, error;
	char c, *p;
	int refused, nres;
	char num[8];
	static char canonnamebuf[MAXDNAME];	/* is it proper here? */

	/* call rcmdsh() with specified remote shell if appropriate. */
	if (!issetugid() && (p = getenv("RSH"))) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, p));
	}

	/* use rsh(1) if non-root and remote port is shell. */
	if (geteuid()) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, NULL));
	}

	pid = getpid();

	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_CANONNAME;
	hints.ai_family = af;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	snprintf(num, sizeof(num), "%d", ntohs(rport));
	error = getaddrinfo(*ahost, num, &hints, &res);
	if (error) {
		fprintf(stderr, "rcmd: getaddrinfo: %s\n",
			gai_strerror(error));
		if (error == EAI_SYSTEM)
			fprintf(stderr, "rcmd: getaddrinfo: %s\n",
				strerror(errno));
		return (-1);
	}

	if (res->ai_canonname &&
	    strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) {
		strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf));
		*ahost = canonnamebuf;
	}
	nres = 0;
	for (ai = res; ai; ai = ai->ai_next)
		nres++;
	ai = res;
	refused = 0;
	sigemptyset(&newmask);
	sigaddset(&newmask, SIGURG);
	_sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask);
	for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
		s = rresvport_af(&lport, ai->ai_family);
		if (s < 0) {
			if (errno != EAGAIN && ai->ai_next) {
				ai = ai->ai_next;
				continue;
			}
			if (errno == EAGAIN)
				fprintf(stderr,
				    "rcmd: socket: All ports in use\n");
			else
				fprintf(stderr, "rcmd: socket: %s\n",
				    strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		_fcntl(s, F_SETOWN, pid);
		if (_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0)
			break;
		_close(s);
		if (errno == EADDRINUSE) {
			lport--;
			continue;
		}
		if (errno == ECONNREFUSED)
			refused = 1;
		if (ai->ai_next == NULL && (!refused || timo > 16)) {
			fprintf(stderr, "%s: %s\n", *ahost, strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		if (nres > 1) {
			int oerrno = errno;

			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "connect to address %s: ", paddr);
			errno = oerrno;
			perror(0);
		}
		if ((ai = ai->ai_next) == NULL) {
			/* refused && timo <= 16 */
			struct timespec time_to_sleep, time_remaining;

			time_to_sleep.tv_sec = timo;
			time_to_sleep.tv_nsec = 0;
			_nanosleep(&time_to_sleep, &time_remaining);
			timo *= 2;
			ai = res;
			refused = 0;
		}
		if (nres > 1) {
			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "Trying %s...\n", paddr);
		}
	}
	lport--;
	if (fd2p == 0) {
		_write(s, "", 1);
		lport = 0;
	} else {
		int s2 = rresvport_af(&lport, ai->ai_family), s3;
		socklen_t len = ai->ai_addrlen;
		int nfds;

		if (s2 < 0)
			goto bad;
		_listen(s2, 1);
		snprintf(num, sizeof(num), "%d", lport);
		if (_write(s, num, strlen(num)+1) != strlen(num)+1) {
			fprintf(stderr,
			    "rcmd: write (setting up stderr): %s\n",
			    strerror(errno));
			_close(s2);
			goto bad;
		}
		nfds = max(s, s2)+1;
		if(nfds > FD_SETSIZE) {
			fprintf(stderr, "rcmd: too many files\n");
			_close(s2);
			goto bad;
		}
again:
		FD_ZERO(&reads);
		FD_SET(s, &reads);
		FD_SET(s2, &reads);
		errno = 0;
		if (_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){
			if (errno != 0)
				fprintf(stderr,
				    "rcmd: select (setting up stderr): %s\n",
				    strerror(errno));
			else
				fprintf(stderr,
				"select: protocol failure in circuit setup\n");
			_close(s2);
			goto bad;
		}
		s3 = _accept(s2, (struct sockaddr *)&from, &len);
		switch (from.ss_family) {
		case AF_INET:
			aport = ntohs(((struct sockaddr_in *)&from)->sin_port);
			break;
#ifdef INET6
		case AF_INET6:
			aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port);
			break;
#endif
		default:
			aport = 0;	/* error */
			break;
		}
		/*
		 * XXX careful for ftp bounce attacks. If discovered, shut them
		 * down and check for the real auxiliary channel to connect.
		 */
		if (aport == 20) {
			_close(s3);
			goto again;
		}
		_close(s2);
		if (s3 < 0) {
			fprintf(stderr,
			    "rcmd: accept: %s\n", strerror(errno));
			lport = 0;
			goto bad;
		}
		*fd2p = s3;
		if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) {
			fprintf(stderr,
			    "socket: protocol failure in circuit setup.\n");
			goto bad2;
		}
	}
	_write(s, locuser, strlen(locuser)+1);
	_write(s, remuser, strlen(remuser)+1);
	_write(s, cmd, strlen(cmd)+1);
	if (_read(s, &c, 1) != 1) {
		fprintf(stderr,
		    "rcmd: %s: %s\n", *ahost, strerror(errno));
		goto bad2;
	}
	if (c != 0) {
		while (_read(s, &c, 1) == 1) {
			_write(STDERR_FILENO, &c, 1);
			if (c == '\n')
				break;
		}
		goto bad2;
	}
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (s);
bad2:
	if (lport)
		_close(*fd2p);
bad:
	_close(s);
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (-1);
}
示例#25
0
bool EthernetServer::hasClient()
{
	_accept();

	return !new_clients.empty();
}