Beispiel #1
0
/*
 * Receive a message.  The socket is re-opened and message read.  The need
 * for a response is indicated.  tcp_tick() fails if peer closed socket.
 */
void RecvMessage(tcp_Socket* tcpSock, int* respond)
{
	auto char buffer[500];
	auto int numBytes;

	tcp_listen(tcpSock, PORT, 0, 0, NULL, 0);
	dispClear();

	/* Wait for connection. */
	while( ! tcp_established( tcpSock ) ) {
		if( ! tcp_tick( (sock_type *) tcpSock ) ) {
			dispPrintf( "ERROR: listening: %s\n", tcpSock->err_msg );
			exit( 99 );
		}
	}

	/*  Wait for some data to appear, or an error... */
	while( 0 == (numBytes = sock_fastread(tcpSock, buffer, sizeof(buffer))) ) {
		if( ! tcp_tick( tcpSock ) ) {
	bad_read:
			dispPrintf( "ERROR: read: %s\n", tcpSock->err_msg );
			exit( 99 );
		}
	}
	if (numBytes == -1) {
		goto bad_read;
	}

	buffer[numBytes] = '\0';
	dispPrintf("%s", buffer);
	*respond = 1;	// Indicate the need for a response

}   /* end RecvMessage() */
Beispiel #2
0
/*
 * Receive a message.  The connected socket and is sent back, and the need
 * for a response is indicated.
 */
void RecvMessage(tcp_Socket* tcpSock)
{
    auto char buffer[500];
    auto int numBytes;

    tcp_listen(tcpSock, PORT, 0, 0, NULL, 0);

    /* Wait for connection. */
    while( ! tcp_established( tcpSock ) )
    {
        if( ! tcp_tick( (sock_type *) tcpSock ) )
        {
            TextGotoXY(&wholewindow, 0, 0 );
            TextPrintf(&wholewindow, "Error: listen");
            return;
        }
    }

    /*  Wait for some data to appear, or an error... */
    while((numBytes = sock_fastread(tcpSock, buffer, sizeof(buffer))) == 0 )
    {
        if( ! tcp_tick( tcpSock ) || numBytes == -1 )
        {
            TextGotoXY(&wholewindow, 0, 0 );
            TextPrintf(&wholewindow, "Error: read");
            return;
        }
    }
    // Display received from other controller
    glBlankScreen();
    TextGotoXY(&wholewindow, 0, 0 );
    TextPrintf(&wholewindow, "Message received:");
    buffer[numBytes] = '\0';
    TextGotoXY(&wholewindow, 0, 1 );
    TextPrintf(&wholewindow, "%s", buffer);

}   /* end RecvMessage() */
Beispiel #3
0
int accept (int s, struct sockaddr *addr, int *addrlen)
{
  Socket  *clone, *socket;
  volatile DWORD   timeout;
  volatile int     newsock = -1;
  volatile int     que_idx;
  volatile int     maxconn;

  socket = _socklist_find (s);

  SOCK_PROLOGUE (socket, "\naccept:%d", s);

  if (!socket->local_addr)
  {
    SOCK_DEBUGF ((socket, ", not bound"));
    SOCK_ERR (ENOTCONN);
    return (-1);
  }

  if (socket->so_type != SOCK_STREAM)
  {
    SOCK_DEBUGF ((socket, ", EOPNOTSUPP"));
    SOCK_ERR (EOPNOTSUPP);
    return (-1);
  }

  if (!(socket->so_options & SO_ACCEPTCONN)) /* listen() not called */
  {
    SOCK_DEBUGF ((socket, ", not SO_ACCEPTCONN"));
    SOCK_ERR (EINVAL);
    return (-1);
  }

  if (!(socket->so_state & (SS_ISLISTENING | SS_ISCONNECTING)))
  {
    SOCK_DEBUGF ((socket, ", not listening"));
    SOCK_ERR (ENOTCONN);
    return (-1);
  }

  if (addr && addrlen)
  {
    if (*addrlen < sizeof(*addr))
    {
      SOCK_DEBUGF ((socket, ", EFAULT"));
      SOCK_ERR (EFAULT);
      return (-1);
    }
    VERIFY_RW (addr, *addrlen);
  }

  /* Get max possible TCBs on listen-queue.
   * Some (or all) may be NULL until a SYN comes in.
   */
  maxconn = socket->backlog;
  if (maxconn < 1 || maxconn > SOMAXCONN)
  {
    SOCK_FATAL (("%s(%d): Illegal socket backlog %d",
                __FILE__, __LINE__, maxconn));
    SOCK_ERR (EINVAL);
    return (-1);
  }

  if (socket->timeout)
       timeout = set_timeout (1000 * socket->timeout);
  else timeout = 0UL;


  if (_sock_sig_setup() < 0)
  {
    SOCK_ERR (EINTR);
    goto accept_fail;
  }

  /* Loop over all queue-slots and accept first connected TCB
   */
  for (que_idx = 0; ; que_idx = (++que_idx % maxconn))
  {
    tcp_Socket *sk = socket->listen_queue [que_idx];

    tcp_tick (NULL);

    SOCK_YIELD();

    /* No SYNs received yet. This shouldn't happen if we called 'accept()'
     * after 'select_s()' said that socket was readable. (At least one
     * connection on the listen-queue).
     */
    if (sk)
    {
      /* This could happen if 'accept()' was called too long after connection
       * was established and then closed by peer. This could also happen if
       * someone did a portscan on us. I.e. he sent 'SYN', we replied with
       * 'SYN+ACK' and he never sent an 'ACK'. Thus we timeout in
       * 'tcp_Retransmitter()' and abort the TCB.
       *
       * Queue slot is in any case ready for another 'SYN' to come and be
       * handled by '_sock_append()'.
       */
      if (sk->state >= tcp_StateLASTACK && sk->ip_type == 0)
      {
        SOCK_DEBUGF ((socket, ", aborted TCB (idx %d)", que_idx));
        listen_free (socket, que_idx);
        continue;
      }

      /* !!to-do: Should maybe loop over all maxconn TCBs and accept the
       *          one with oldest 'syn_timestamp'.
       */
      if (tcp_established(sk))
      {
        SOCK_DEBUGF ((socket, ", connected! (idx %d)", que_idx));
        break;
      }
    }

    /* We've polled all listen-queue slots and none are connected.
     * Return fail if socket is non-blocking.
     */
    if (que_idx == maxconn-1 && (socket->so_state & SS_NBIO))
    {
      SOCK_DEBUGF ((socket, ", would block"));
      SOCK_ERR (EWOULDBLOCK);
      goto accept_fail;
    }

    if (chk_timeout(timeout))
    {
      SOCK_DEBUGF ((socket, ", ETIMEDOUT"));
      SOCK_ERR (ETIMEDOUT);
      goto accept_fail;
    }
  }

  /* We're here only when above 'tcp_established()' succeeded.
   * Now duplicate 'socket' into a new listening socket 'clone'
   * with handle 'newsock'.
   */
  _sock_enter_scope();
  newsock = dup_bind (socket, &clone, que_idx);
  if (newsock < 0)
     goto accept_fail;

  if (alloc_addr(socket, clone) < 0)
  {
    SOCK_DEL_FD (newsock);
    goto accept_fail;
  }

  /* Clone is connected, but *not* listening/accepting.
   * Note: other 'so_state' bits from parent is unchanged.
   *       e.g. clone may be non-blocking.
   */
  clone->so_state   |=  SS_ISCONNECTED;
  clone->so_state   &= ~(SS_ISLISTENING | SS_ISCONNECTING);
  clone->so_options &= ~SO_ACCEPTCONN;

  /* Prevent a PUSH on first segment sent.
   */
  sock_noflush ((sock_type*)clone->tcp_sock);

  SOCK_DEBUGF ((clone, "\nremote %s (%d)",
                inet_ntoa (clone->remote_addr->sin_addr),
                ntohs (clone->remote_addr->sin_port)));

  if (addr && addrlen)
  {
    struct sockaddr_in *sa = (struct sockaddr_in*)addr;

    sa->sin_family = AF_INET;
    sa->sin_port   = clone->remote_addr->sin_port;
    sa->sin_addr   = clone->remote_addr->sin_addr;
    memset (sa->sin_zero, 0, sizeof(sa->sin_zero));
    *addrlen = sizeof(*sa);
  }

  _sock_leave_scope();
  _sock_sig_restore();
  return (newsock);

accept_fail:
  _sock_leave_scope();
  _sock_sig_restore();
  return (-1);
}