예제 #1
0
파일: tcp_conn.c 프로젝트: KimMui/i2sTest
FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct tcp_iphdr_s *buf)
{
  FAR struct tcp_conn_s *conn = tcp_alloc();
  if (conn)
    {
      /* Fill in the necessary fields for the new connection. */

      conn->rto           = TCP_RTO;
      conn->timer         = TCP_RTO;
      conn->sa            = 0;
      conn->sv            = 4;
      conn->nrtx          = 0;
      conn->lport         = buf->destport;
      conn->rport         = buf->srcport;
      conn->mss           = TCP_INITIAL_MSS;
      net_ipaddr_copy(conn->ripaddr, net_ip4addr_conv32(buf->srcipaddr));
      conn->tcpstateflags = TCP_SYN_RCVD;

      tcp_initsequence(conn->sndseq);
      conn->unacked       = 1;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      conn->expired       = 0;
      conn->isn           = 0;
      conn->sent          = 0;
#endif

      /* rcvseq should be the seqno from the incoming packet + 1. */

      memcpy(conn->rcvseq, buf->seqno, 4);

#ifdef CONFIG_NET_TCP_READAHEAD
      /* Initialize the list of TCP read-ahead buffers */

      IOB_QINIT(&conn->readahead);
#endif

#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      /* Initialize the write buffer lists */

      sq_init(&conn->write_q);
      sq_init(&conn->unacked_q);
#endif

      /* And, finally, put the connection structure into the active list.
       * Interrupts should already be disabled in this context.
       */

      dq_addlast(&conn->node, &g_active_tcp_connections);
    }

  return conn;
}
예제 #2
0
파일: tcp_conn.c 프로젝트: KimMui/i2sTest
int tcp_connect(FAR struct tcp_conn_s *conn,
                FAR const struct sockaddr_in *addr)
#endif
{
  net_lock_t flags;
  int port;

  /* The connection is expected to be in the TCP_ALLOCATED state.. i.e.,
   * allocated via up_tcpalloc(), but not yet put into the active connections
   * list.
   */

  if (!conn || conn->tcpstateflags != TCP_ALLOCATED)
    {
      return -EISCONN;
    }

  /* If the TCP port has not already been bound to a local port, then select
   * one now.
   */

  flags = net_lock();
  port = tcp_selectport(ntohs(conn->lport));
  net_unlock(flags);

  if (port < 0)
    {
      return port;
    }

  /* Initialize and return the connection structure, bind it to the port number */

  conn->tcpstateflags = TCP_SYN_SENT;
  tcp_initsequence(conn->sndseq);

  conn->mss        = TCP_INITIAL_MSS;
  conn->unacked    = 1;    /* TCP length of the SYN is one. */
  conn->nrtx       = 0;
  conn->timer      = 1;    /* Send the SYN next time around. */
  conn->rto        = TCP_RTO;
  conn->sa         = 0;
  conn->sv         = 16;   /* Initial value of the RTT variance. */
  conn->lport      = htons((uint16_t)port);
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
  conn->expired    = 0;
  conn->isn        = 0;
  conn->sent       = 0;
#endif

  /* The sockaddr port is 16 bits and already in network order */

  conn->rport = addr->sin_port;

  /* The sockaddr address is 32-bits in network order. */

  net_ipaddr_copy(conn->ripaddr, addr->sin_addr.s_addr);

#ifdef CONFIG_NET_TCP_READAHEAD
  /* Initialize the list of TCP read-ahead buffers */

  IOB_QINIT(&conn->readahead);
#endif

#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
  /* Initialize the TCP write buffer lists */

  sq_init(&conn->write_q);
  sq_init(&conn->unacked_q);
#endif

  /* And, finally, put the connection structure into the active
   * list. Because g_active_tcp_connections is accessed from user level and
   * interrupt level, code, it is necessary to keep interrupts disabled during
   * this operation.
   */

  flags = net_lock();
  dq_addlast(&conn->node, &g_active_tcp_connections);
  net_unlock(flags);

  return OK;
}
예제 #3
0
파일: tcp_conn.c 프로젝트: a1ien/nuttx
FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
                                        FAR struct tcp_hdr_s *tcp)
{
  FAR struct tcp_conn_s *conn;
  uint8_t domain;
  int ret;

  /* Get the appropriate IP domain */

#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv4)
  bool ipv6 = IFF_IS_IPv6(dev->d_flags);
  domain = ipv6 ? PF_INET6 : PF_INET;
#elif defined(CONFIG_NET_IPv4)
  domain = PF_INET;
#else /* defined(CONFIG_NET_IPv6) */
  domain = PF_INET6;
#endif

  /* Allocate the connection structure */

  conn = tcp_alloc(domain);
  if (conn)
    {
      /* Set up the local address (laddr) and the remote address (raddr)
       * that describes the TCP connection.
       */

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
      if (ipv6)
#endif
        {
          FAR struct ipv6_hdr_s *ip = IPv6BUF;

          /* Set the IPv6 specific MSS and the IPv6 locally bound address */

          conn->mss = TCP_IPv6_INITIAL_MSS(dev);
          net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr);
#ifdef CONFIG_NETDEV_MULTINIC
          net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr);

          /* We now have to filter all outgoing transfers so that they use
           * only the MSS of this device.
           */

          DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
          conn->dev = dev;
#endif

          /* Find the device that can receive packets on the network
           * associated with this local address.
           */

          ret = tcp_remote_ipv6_device(conn);
        }
#endif /* CONFIG_NET_IPv6 */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
      else
#endif
        {
          FAR struct ipv4_hdr_s *ip = IPv4BUF;

          /* Set the IPv6 specific MSS and the IPv4 bound remote address. */

          conn->mss = TCP_IPv4_INITIAL_MSS(dev);
          net_ipv4addr_copy(conn->u.ipv4.raddr,
                            net_ip4addr_conv32(ip->srcipaddr));

#ifdef CONFIG_NETDEV_MULTINIC
          /* Set the local address as well */

          net_ipv4addr_copy(conn->u.ipv4.laddr,
                            net_ip4addr_conv32(ip->destipaddr));

          /* We now have to filter all outgoing transfers so that they use
           * only the MSS of this device.
           */

          DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
          conn->dev = dev;
#endif

          /* Find the device that can receive packets on the network
           * associated with this local address.
           */

          ret = tcp_remote_ipv4_device(conn);
        }
#endif /* CONFIG_NET_IPv4 */

      /* Verify that a network device that can provide packets to this
       * local address was found.
       */

      if (ret < 0)
        {
          /* If no device is found, then the address is not reachable.
           * That should be impossible in this context and we should
           * probably really just assert here.
           */

          nerr("ERROR: Failed to find network device: %d\n", ret);
          tcp_free(conn);
          return NULL;
        }

      /* Fill in the necessary fields for the new connection. */

      conn->rto           = TCP_RTO;
      conn->timer         = TCP_RTO;
      conn->sa            = 0;
      conn->sv            = 4;
      conn->nrtx          = 0;
      conn->lport         = tcp->destport;
      conn->rport         = tcp->srcport;
      conn->tcpstateflags = TCP_SYN_RCVD;

      tcp_initsequence(conn->sndseq);
      conn->unacked       = 1;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      conn->expired       = 0;
      conn->isn           = 0;
      conn->sent          = 0;
      conn->sndseq_max    = 0;
#endif

      /* rcvseq should be the seqno from the incoming packet + 1. */

      memcpy(conn->rcvseq, tcp->seqno, 4);

#ifdef CONFIG_NET_TCP_READAHEAD
      /* Initialize the list of TCP read-ahead buffers */

      IOB_QINIT(&conn->readahead);
#endif

#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      /* Initialize the write buffer lists */

      sq_init(&conn->write_q);
      sq_init(&conn->unacked_q);
#endif

      /* And, finally, put the connection structure into the active list.
       * Interrupts should already be disabled in this context.
       */

      dq_addlast(&conn->node, &g_active_tcp_connections);
    }

  return conn;
}
예제 #4
0
파일: tcp_conn.c 프로젝트: a1ien/nuttx
int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
{
  int port;
  int ret;

  /* The connection is expected to be in the TCP_ALLOCATED state.. i.e.,
   * allocated via up_tcpalloc(), but not yet put into the active connections
   * list.
   */

  if (!conn || conn->tcpstateflags != TCP_ALLOCATED)
    {
      return -EISCONN;
    }

  /* If the TCP port has not already been bound to a local port, then select
   * one now.  We assume that the IP address has been bound to a local device,
   * but the port may still be INPORT_ANY.
   */

  net_lock();

#ifdef CONFIG_NETDEV_MULTINIC
  /* If there are multiple network devices, then we need to pass the local,
   * bound address.  This is needed because port unique-ness is only for a
   * given network.
   *
   * This is complicated by the fact that the local address may be either an
   * IPv4 or an IPv6 address.
   */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
  if (conn->domain == PF_INET)
#endif
    {
      /* Select a port that is unique for this IPv4 local address (host
       * order).
       */

      port = tcp_selectport(PF_INET,
                            (FAR const union ip_addr_u *)&conn->u.ipv4.laddr,
                            ntohs(conn->lport));
    }
#endif /* CONFIG_NET_IPv4 */

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
  else
#endif
    {
      /* Select a port that is unique for this IPv6 local address (host
       * order).
       */

      port = tcp_selectport(PF_INET6,
                            (FAR const union ip_addr_u *)conn->u.ipv6.laddr,
                            ntohs(conn->lport));
    }
#endif /* CONFIG_NET_IPv6 */

#else /* CONFIG_NETDEV_MULTINIC */
  /* Select the next available port number.  This is only one network device
   * so we do not have to bother with all of the IPv4/IPv6 local address
   * silliness.
   */

  port = tcp_selectport(ntohs(conn->lport));

#endif /* CONFIG_NETDEV_MULTINIC */

  /* Did we have a port assignment? */

  if (port < 0)
    {
      ret = port;
      goto errout_with_lock;
    }

  /* Set up the local address (laddr) and the remote address (raddr) that
   * describes the TCP connection.
   */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
  if (conn->domain == PF_INET)
#endif
    {
      FAR const struct sockaddr_in *inaddr =
        (FAR const struct sockaddr_in *)addr;

      /* Save MSS and the port from the sockaddr (already in network order) */

      conn->mss    = MIN_IPv4_TCP_INITIAL_MSS;
      conn->rport  = inaddr->sin_port;

      /* The sockaddr address is 32-bits in network order. */

      net_ipv4addr_copy(conn->u.ipv4.raddr, inaddr->sin_addr.s_addr);

      /* Find the device that can receive packets on the network associated
       * with this remote address.
       */

      ret = tcp_remote_ipv4_device(conn);
    }
#endif /* CONFIG_NET_IPv4 */

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
  else
#endif
    {
      FAR const struct sockaddr_in6 *inaddr =
        (FAR const struct sockaddr_in6 *)addr;

      /* Save MSS and the port from the sockaddr (already in network order) */

      conn->mss     = MIN_IPv6_TCP_INITIAL_MSS;
      conn->rport   = inaddr->sin6_port;

      /* The sockaddr address is 128-bits in network order. */

      net_ipv6addr_copy(conn->u.ipv6.raddr, inaddr->sin6_addr.s6_addr16);

      /* Find the device that can receive packets on the network associated
       * with this local address.
       */

      ret = tcp_remote_ipv6_device(conn);
    }
#endif /* CONFIG_NET_IPv6 */

  /* Verify that a network device that can provide packets to this local
   * address was found.
   */

  if (ret < 0)
    {
      /* If no device is found, then the address is not reachable.  That
       * should be impossible in this context and we should probably really
       * just assert here.
       */

      nerr("ERROR: Failed to find network device: %d\n", ret);
      goto errout_with_lock;
    }

  /* Initialize and return the connection structure, bind it to the port
   * number.  At this point, we do not know the size of the initial MSS We
   * know the total size of the packet buffer, but we don't yet know the
   * size of link layer header.
   */

  conn->tcpstateflags = TCP_SYN_SENT;
  tcp_initsequence(conn->sndseq);

  conn->unacked    = 1;    /* TCP length of the SYN is one. */
  conn->nrtx       = 0;
  conn->timer      = 1;    /* Send the SYN next time around. */
  conn->rto        = TCP_RTO;
  conn->sa         = 0;
  conn->sv         = 16;   /* Initial value of the RTT variance. */
  conn->lport      = htons((uint16_t)port);
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
  conn->expired    = 0;
  conn->isn        = 0;
  conn->sent       = 0;
  conn->sndseq_max = 0;
#endif

#ifdef CONFIG_NET_TCP_READAHEAD
  /* Initialize the list of TCP read-ahead buffers */

  IOB_QINIT(&conn->readahead);
#endif

#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
  /* Initialize the TCP write buffer lists */

  sq_init(&conn->write_q);
  sq_init(&conn->unacked_q);
#endif

  /* And, finally, put the connection structure into the active list. */

  dq_addlast(&conn->node, &g_active_tcp_connections);
  ret = OK;

errout_with_lock:
  net_unlock();
  return ret;
}