Beispiel #1
0
void net_lostconnection(FAR struct socket *psock, uint16_t flags)
{
  net_lock_t save;

  DEBUGASSERT(psock != NULL && psock->s_conn != NULL);

  /* Close the connection */

  save = net_lock();
  connection_closed(psock, flags);

  /* Stop the network monitor */

  net_stopmonitor((FAR struct tcp_conn_s *)psock->s_conn);
  net_unlock(save);
}
Beispiel #2
0
static inline void tcp_teardown_callbacks(struct tcp_connect_s *pstate,
                                          int status)
{
  FAR struct uip_conn *conn = pstate->tc_conn;

  /* Make sure that no further interrupts are processed */

  uip_tcpcallbackfree(conn, pstate->tc_cb);

  pstate->tc_cb = NULL;

  /* If we successfully connected, we will continue to monitor the connection
   * state via callbacks.
   */

  if (status < 0)
    {
      /* Failed to connect. Stop the connection event monitor */

      net_stopmonitor(conn);
    }
}
Beispiel #3
0
int psock_close(FAR struct socket *psock)
{
  int err;

  /* Verify that the sockfd corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      err = EBADF;
      goto errout;
    }

  /* We perform the uIP close operation only if this is the last count on
   * the socket. (actually, I think the socket crefs only takes the values
   * 0 and 1 right now).
   *
   * It is possible for a psock to have no connection, e.g. a TCP socket
   * waiting in accept.
   */

  if (psock->s_crefs <= 1 && psock->s_conn != NULL)
    {
      /* Perform uIP side of the close depending on the protocol type */

      switch (psock->s_type)
        {
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM)
          case SOCK_STREAM:
            {
#ifdef CONFIG_NET_LOCAL_STREAM
#ifdef CONFIG_NET_TCP
              if (psock->s_domain == PF_LOCAL)
#endif
                {
                  /* Release our reference to the local connection structure */

                  local_close(psock);
                }
#endif /* CONFIG_NET_LOCAL_STREAM */

#ifdef CONFIG_NET_TCP
#ifdef CONFIG_NET_LOCAL_STREAM
              else
#endif
                {
                  FAR struct tcp_conn_s *conn = psock->s_conn;

                  /* Is this the last reference to the connection structure
                   * (there could be more if the socket was dup'ed).
                   */

                  if (conn->crefs <= 1)
                    {
                      /* Yes... then perform the disconnection now */

                      tcp_unlisten(conn); /* No longer accepting connections */
                      conn->crefs = 0;    /* Discard our reference to the connection */

                      /* Break any current connections */

                      err = netclose_disconnect(psock);
                      if (err < 0)
                        {
                          /* This would normally occur only if there is a
                           * timeout from a lingering close.
                           */

                          goto errout_with_psock;
                        }

                      /* Stop the network monitor */

                      net_stopmonitor(conn);
                    }
                  else
                    {
                      /* No.. Just decrement the reference count */

                      conn->crefs--;
                    }
                }
#endif /* CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM */
            }
            break;
#endif

#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_LOCAL_DGRAM)
          case SOCK_DGRAM:
            {
#ifdef CONFIG_NET_LOCAL_DGRAM
#ifdef CONFIG_NET_UDP
              if (psock->s_domain == PF_LOCAL)
#endif
                {
                  /* Release our reference to the local connection structure */

                  local_close(psock);
                }
#endif /* CONFIG_NET_LOCAL_DGRAM */

#ifdef CONFIG_NET_UDP
#ifdef CONFIG_NET_LOCAL_DGRAM
              else
#endif
                {
                  FAR struct udp_conn_s *conn = psock->s_conn;

                  /* Is this the last reference to the connection structure
                   * (there could be more if the socket was dup'ed).
                   */

                  if (conn->crefs <= 1)
                    {
                      /* Yes... free the connection structure */

                      conn->crefs = 0;
                      udp_free(psock->s_conn);
                    }
                  else
                    {
                      /* No.. Just decrement the reference count */

                      conn->crefs--;
                    }
                }
#endif /* CONFIG_NET_UDP || CONFIG_NET_LOCAL_DGRAM */
            }
            break;
#endif

#ifdef CONFIG_NET_PKT
          case SOCK_RAW:
            {
              FAR struct pkt_conn_s *conn = psock->s_conn;

              /* Is this the last reference to the connection structure (there
               * could be more if the socket was dup'ed).
               */

              if (conn->crefs <= 1)
                {
                  /* Yes... free the connection structure */

                  conn->crefs = 0;          /* No more references on the connection */
                  pkt_free(psock->s_conn);  /* Free uIP resources */
                }
              else
                {
                  /* No.. Just decrement the reference count */

                  conn->crefs--;
                }
            }
            break;
#endif

          default:
            err = EBADF;
            goto errout;
        }
    }

  /* Then release our reference on the socket structure containing the connection */

  sock_release(psock);
  return OK;

#ifdef CONFIG_NET_TCP
errout_with_psock:
  sock_release(psock);
#endif

errout:
  set_errno(err);
  return ERROR;
}