⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpio.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
          continue;        }      GNUNET_mutex_lock (sock->destroylock);      if (sock->sock != NULL)        {          GNUNET_free (host);          GNUNET_mutex_unlock (sock->destroylock);          GNUNET_free (soaddr);          return GNUNET_OK;        }      if (sock->dead == GNUNET_YES)        {          GNUNET_free (host);          GNUNET_mutex_unlock (sock->destroylock);          GNUNET_free (soaddr);          return GNUNET_SYSERR;        }      if (soaddr->sa_family == AF_INET)        {          ((struct sockaddr_in *) soaddr)->sin_port = htons (port);          osock = SOCKET (PF_INET, SOCK_STREAM, 0);        }      else        {#ifdef PF_INET6          ((struct sockaddr_in6 *) soaddr)->sin6_port = htons (port);          osock = SOCKET (PF_INET6, SOCK_STREAM, 0);#else          osock = -1;          errno = EAFNOSUPPORT;#endif        }      if (osock == -1)        {          GNUNET_GE_LOG_STRERROR (sock->ectx,                                  GNUNET_GE_ERROR | GNUNET_GE_USER |                                  GNUNET_GE_ADMIN | GNUNET_GE_BULK, "socket");          GNUNET_mutex_unlock (sock->destroylock);          GNUNET_free (soaddr);          ADVANCE ();          continue;        }      sock->sock = GNUNET_socket_create (sock->ectx, NULL, osock);      GNUNET_socket_set_blocking (sock->sock, GNUNET_NO);      ret = CONNECT (osock, soaddr, socklen);      GNUNET_free (soaddr);      if ((ret != 0) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK))        {          GNUNET_GE_LOG (sock->ectx,                         GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,                         _("Cannot connect to %s:%u: %s\n"),                         host, port, STRERROR (errno));          GNUNET_socket_destroy (sock->sock);          sock->sock = NULL;          GNUNET_mutex_unlock (sock->destroylock);          if (errno == ECONNREFUSED)            RETRY ();           /* gnunetd may just be restarting */          else            ADVANCE ();          continue;        }      /* we call select() first with a timeout of WAIT_SECONDS to         avoid blocking on a later write indefinitely;         Important if a local firewall decides to just drop         the TCP handshake... */      FD_ZERO (&rset);      FD_ZERO (&wset);      FD_ZERO (&eset);      FD_SET (osock, &wset);      FD_SET (osock, &eset);      timeout.tv_sec = 0;      timeout.tv_usec = DELAY_PER_RETRY * TRIES_PER_AF * 1000;      errno = 0;      select_start = GNUNET_get_time ();      ret = SELECT (osock + 1, &rset, &wset, &eset, &timeout);      if (ret == -1)        {          if (errno != EINTR)            GNUNET_GE_LOG_STRERROR (sock->ectx,                                    GNUNET_GE_WARNING | GNUNET_GE_USER |                                    GNUNET_GE_BULK, "select");          GNUNET_socket_destroy (sock->sock);          sock->sock = NULL;          GNUNET_mutex_unlock (sock->destroylock);          if ((GNUNET_get_time () - select_start >               TRIES_PER_AF * DELAY_PER_RETRY) || (errno != EINTR))            ADVANCE ();         /* spend enough time trying here */          else            RETRY ();          continue;        }      if ((FD_ISSET (osock, &eset)) || (!FD_ISSET (osock, &wset)))        {          GNUNET_socket_destroy (sock->sock);          sock->sock = NULL;          GNUNET_mutex_unlock (sock->destroylock);          if (GNUNET_get_time () - select_start >              TRIES_PER_AF * DELAY_PER_RETRY)            ADVANCE ();         /* spend enough time trying here */          else            RETRY ();          continue;        }      soerr = 0;      soerrlen = sizeof (soerr);      ret = GETSOCKOPT (osock, SOL_SOCKET, SO_ERROR, &soerr, &soerrlen);      if (ret != 0)        GNUNET_GE_LOG_STRERROR (sock->ectx,                                GNUNET_GE_WARNING | GNUNET_GE_USER |                                GNUNET_GE_BULK, "getsockopt");      if ((soerr != 0) || (ret != 0 && (errno == ENOTSOCK || errno == EBADF)))        {          GNUNET_socket_destroy (sock->sock);          sock->sock = NULL;          GNUNET_mutex_unlock (sock->destroylock);          if (GNUNET_get_time () - select_start >              TRIES_PER_AF * DELAY_PER_RETRY)            ADVANCE ();         /* spend enough time trying here */          else            RETRY ();          continue;        }      /* yayh! connected! */      break;    }  GNUNET_free (host);  GNUNET_socket_set_blocking (sock->sock, GNUNET_YES);  GNUNET_mutex_unlock (sock->destroylock);#undef ADVANCE#undef RETRY#undef TRIES_PER_AF#undef DELAY_PER_RETRY  return GNUNET_OK;}/** * Write to a GNUnet TCP socket.  Will also potentially complete the * sending of a previous non-blocking GNUNET_client_connection_write call. * * @param sock the socket to write to * @param buffer the buffer to write * @return GNUNET_OK if the write was sucessful, otherwise GNUNET_SYSERR. */intGNUNET_client_connection_write (struct GNUNET_ClientServerConnection *sock,                                const GNUNET_MessageHeader * buffer){  size_t size;  size_t sent;  int res;  GNUNET_mutex_lock (sock->destroylock);  GNUNET_mutex_lock (sock->writelock);  if (GNUNET_SYSERR == GNUNET_client_connection_ensure_connected (sock))    {      GNUNET_mutex_unlock (sock->writelock);      GNUNET_mutex_unlock (sock->destroylock);      return GNUNET_SYSERR;    }  GNUNET_mutex_unlock (sock->destroylock);  GNUNET_GE_ASSERT (NULL, sock->sock != NULL);  size = ntohs (buffer->size);  res =    GNUNET_socket_send (sock->sock, GNUNET_NC_COMPLETE_TRANSFER, buffer, size,                        &sent);  if ((res != GNUNET_YES) || (sent != size))    {      GNUNET_mutex_unlock (sock->writelock);      GNUNET_client_connection_close_temporarily (sock);      return GNUNET_SYSERR;    }  GNUNET_mutex_unlock (sock->writelock);  return GNUNET_OK;}intGNUNET_client_connection_read (struct GNUNET_ClientServerConnection *sock,                               GNUNET_MessageHeader ** buffer){  int res;  size_t pos;  char *buf;  unsigned short size;  GNUNET_MessageReturnErrorMessage *rem;  GNUNET_mutex_lock (sock->destroylock);  GNUNET_mutex_lock (sock->readlock);  if (GNUNET_OK != GNUNET_client_connection_ensure_connected (sock))    {      GNUNET_mutex_unlock (sock->readlock);      GNUNET_mutex_unlock (sock->destroylock);      return GNUNET_SYSERR;    }  GNUNET_mutex_unlock (sock->destroylock);  GNUNET_GE_ASSERT (NULL, sock->sock != NULL);  while (1)    {      pos = 0;      res = 0;      if ((GNUNET_OK != GNUNET_socket_recv (sock->sock,                                            GNUNET_NC_COMPLETE_TRANSFER,                                            &size,                                            sizeof (unsigned short),                                            &pos))          || (pos != sizeof (unsigned short)))        {          GNUNET_mutex_unlock (sock->readlock);          GNUNET_client_connection_close_temporarily (sock);          return GNUNET_SYSERR;        }      size = ntohs (size);      if (size < sizeof (GNUNET_MessageHeader))        {          GNUNET_GE_BREAK (sock->ectx, 0);          GNUNET_mutex_unlock (sock->readlock);          GNUNET_client_connection_close_temporarily (sock);          return GNUNET_SYSERR; /* invalid header */        }      buf = GNUNET_malloc (size);      if ((GNUNET_OK != GNUNET_socket_recv (sock->sock,                                            GNUNET_NC_COMPLETE_TRANSFER,                                            &buf[pos],                                            size - pos,                                            &pos)) ||          (pos + sizeof (unsigned short) != size))        {          GNUNET_free (buf);          GNUNET_mutex_unlock (sock->readlock);          GNUNET_client_connection_close_temporarily (sock);          return GNUNET_SYSERR;        }#if DEBUG_TCPIO      GNUNET_GE_LOG (sock->ectx,                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                     "Successfully received %d bytes from TCP socket.\n",                     size);#endif      *buffer = (GNUNET_MessageHeader *) buf;      (*buffer)->size = htons (size);      if (ntohs ((*buffer)->type) != GNUNET_CS_PROTO_RETURN_ERROR)        break;                  /* got actual message! */      rem = (GNUNET_MessageReturnErrorMessage *) * buffer;      if (ntohs (rem->header.size) <          sizeof (GNUNET_MessageReturnErrorMessage))        {          GNUNET_GE_BREAK (sock->ectx, 0);          GNUNET_mutex_unlock (sock->readlock);          GNUNET_client_connection_close_temporarily (sock);          GNUNET_free (buf);          return GNUNET_SYSERR;        }      size =        ntohs (rem->header.size) - sizeof (GNUNET_MessageReturnErrorMessage);      GNUNET_GE_LOG (sock->ectx, ntohl (rem->kind), "%.*s", (int) size,                     &rem[1]);      GNUNET_free (rem);    }                           /* while (1) */  GNUNET_mutex_unlock (sock->readlock);  return GNUNET_OK;             /* success */}/** * Obtain a return value from a remote call from TCP. * * @param sock the TCP socket * @param ret the return value from TCP * @return GNUNET_SYSERR on error, GNUNET_OK if the return value was read * successfully */intGNUNET_client_connection_read_result (struct GNUNET_ClientServerConnection                                      *sock, int *ret){  GNUNET_MessageReturnValue *rv;  rv = NULL;  if (GNUNET_SYSERR ==      GNUNET_client_connection_read (sock, (GNUNET_MessageHeader **) & rv))    return GNUNET_SYSERR;  if ((ntohs (rv->header.size) != sizeof (GNUNET_MessageReturnValue)) ||      (ntohs (rv->header.type) != GNUNET_CS_PROTO_RETURN_VALUE))    {      GNUNET_GE_LOG (sock->ectx,                     GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK,                     _                     ("Reading result from gnunetd failed, reply invalid!\n"));      GNUNET_free (rv);      return GNUNET_SYSERR;    }  *ret = ntohl (rv->return_value);  GNUNET_free (rv);  return GNUNET_OK;}/** * Send a return value to the caller of a remote call via * TCP. * @param sock the TCP socket * @param ret the return value to send via TCP * @return GNUNET_SYSERR on error, GNUNET_OK if the return value was *         send successfully */intGNUNET_client_connection_write_result (struct GNUNET_ClientServerConnection                                       *sock, int ret){  GNUNET_MessageReturnValue rv;  rv.header.size = htons (sizeof (GNUNET_MessageReturnValue));  rv.header.type = htons (GNUNET_CS_PROTO_RETURN_VALUE);  rv.return_value = htonl (ret);  return GNUNET_client_connection_write (sock, &rv.header);}/*  end of tcpio.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -