Exemplo n.º 1
0
static
void chr_tcp_init_connection (char_tcp_t *drv)
{
	tcp_set_nodelay (drv->fd, 1);

	drv->telnet_state = CHAR_TCP_DATA;

	if (drv->telnet && drv->telnetinit) {
		/* Instruct telnet client to switch to character mode. */
		telnet_do (drv, TELNET_OPT_BINARY);
		telnet_will (drv, TELNET_OPT_ECHO);
		telnet_will (drv, TELNET_OPT_SUPPRESS_GO_AHEAD);
	}
}
/**
 * @fn        THRET accept_thread(void *arg)
 * @brief     The accepting thread for TCP connection.
 * @param[in] arg The argument of accepting thread: CONN_BCAP_SERVER.
 */
static THRET THTYPE
accept_thread(void *arg)
{
#if !defined(THRET)
  THRET ret = (THRET)NULL;
#endif

  int client;
  HRESULT hr;
  volatile struct CONN_BCAP_SERVER *child;
  struct CONN_BCAP_SERVER *bcap_param = (struct CONN_BCAP_SERVER *) arg;
  MUTEX mutex;

  /* Initializes mutex */
  bcap_param->relation_mutex = &mutex;
  hr = initialize_mutex(&mutex);
  if(FAILED(hr)) goto exit_proc;

  while(1) {
    hr = wait_event(&bcap_param->term_main_evt, 300);
    if(SUCCEEDED(hr)) {
      break;
    }

    if(bcap_param->num_child < BCAP_CLIENT_MAX) {
      hr = tcp_accept(bcap_param->device.sock, &client);
      if(SUCCEEDED(hr)) {
        /* Sets no delay option */
        tcp_set_nodelay(client, 1);

        /* Sets keep alive option */
        tcp_set_keepalive(client, KEEPALIVE_ENABLE, KEEPALIVE_IDLE,
            KEEPALIVE_INTERVAL, KEEPALIVE_COUNT);

        /* Adds child */
        change_relation(bcap_param, ADD_CHILD, &client);
      }
    }

    /* Deletes child */
    change_relation(bcap_param, DELETE_CHILD, NULL);
  }

exit_proc:
  /* Ends all children thread */
  child = bcap_param->node1;
  while(child != NULL) {
    set_event((EVENT *) &child->term_main_evt);
    exit_thread(child->main_thread);

    child = bcap_param->node1;
  }

  /* Deletes child */
  change_relation(bcap_param, DELETE_CHILD, NULL);

  /* Releases mutex */
  release_mutex(&mutex);

#if !defined(THRET)
  return ret;
#endif
}
Exemplo n.º 3
0
ya_result
tcp_input_output_stream_connect_sockaddr(const struct sockaddr *sa, input_stream *istream_, output_stream *ostream_, struct sockaddr *bind_from, u8 to_sec)
{
    int fd;

    while((fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
    {
        int err = errno;
        
        if(err != EINTR)
        {
            return MAKE_ERRNO_ERROR(err);
        }
    }
    
    /*
     * Bind the socket if required.
     */

    if(bind_from != NULL)
    {
        while((bind(fd, bind_from, sizeof(socketaddress))) < 0)
        {
            int err = errno;

            if(err != EINTR)
            {
                close_ex(fd); /* could clear errno */

                return MAKE_ERRNO_ERROR(err);
            }
        }
    }

    int ssec, susec, rsec, rusec;

    tcp_get_sendtimeout(fd, &ssec, &susec);
    tcp_get_recvtimeout(fd, &rsec, &rusec);

    tcp_set_sendtimeout(fd, to_sec, 0);
    tcp_set_recvtimeout(fd, to_sec, 0);
    
    tcp_set_nodelay(fd, tcp_nodelay);
    tcp_set_cork(fd, tcp_cork);

#if HAS_SOCKADDR_SA_LEN
    while(connect(fd, sa, sa->sa_len) < 0)
#else
    while(connect(fd, sa, sizeof(socketaddress)) < 0)
#endif
    {
        int err = errno;
        
        if(err != EINTR)
        {
            close_ex(fd);
            
            // Linux quirk
            
            if(err == EINPROGRESS)
            {
                err = ETIMEDOUT;
            }
            
            return MAKE_ERRNO_ERROR(err);
        }
    }
    
    /* can only fail if fd < 0, which is never the case here */
    
    fd_input_stream_attach(istream_, fd);
    fd_output_stream_attach_noclose(ostream_, fd);

    tcp_set_sendtimeout(fd, ssec, susec);
    tcp_set_recvtimeout(fd, rsec, rusec);

    return fd;
}