Example #1
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).
   */

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

      switch (psock->s_type)
        {
#ifdef CONFIG_NET_TCP
          case SOCK_STREAM:
            {
              struct uip_conn *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 */

                  uip_unlisten(conn);          /* No longer accepting connections */
                  netclose_disconnect(psock);  /* Break any current connections */
                  conn->crefs = 0;             /* No more references on the connection */
                  uip_tcpfree(conn);           /* Free uIP resources */
                }
              else
                {
                  /* No.. Just decrement the reference count */

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

#ifdef CONFIG_NET_UDP
          case SOCK_DGRAM:
            {
              struct uip_udp_conn *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 */
                  uip_udpfree(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;

errout:
  errno = err;
  return ERROR;
}
Example #2
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).
   */

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

      switch (psock->s_type)
        {
#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

#ifdef CONFIG_NET_TCP
          case SOCK_STREAM:
            {
              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 */
                  err = netclose_disconnect(psock);  /* Break any current connections */
                  if (err < 0)
                    {
                      /* This would normally occur only if there is a timeout
                       * from a lingering close.
                       */

                      goto errout_with_psock;
                    }
                }
              else
                {
                  /* No.. Just decrement the reference count */

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

#ifdef CONFIG_NET_UDP
          case SOCK_DGRAM:
            {
              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;          /* No more references on the connection */
                  udp_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;
}
Example #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;
}