Example #1
0
/* Closes given ne_socket */
int ne_sock_close(ne_socket *sock)
{
    int ret;

#if defined(HAVE_OPENSSL)
    if (sock->ssl) {
	SSL_shutdown(sock->ssl);
	SSL_free(sock->ssl);
    }
#elif defined(HAVE_GNUTLS)
    if (sock->ssl) {
        do {
            ret = gnutls_bye(sock->ssl, GNUTLS_SHUT_RDWR);
        } while (ret < 0
                 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN));
    }
#endif

    if (sock->fd < 0)
        ret = 0;
    else
        ret = ne_close(sock->fd);
    ne_free(sock);
    return ret;
}
Example #2
0
ne_socket *ne_sock_connect(const ne_inet_addr *addr, unsigned int portnum)
{
    int fd;
    int len, val;

#ifdef USE_GETADDRINFO
    /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
     * implementations do not set ai_socktype, e.g. RHL6.2. */
    fd = socket(addr->ai_family, SOCK_STREAM, addr->ai_protocol);
#else
    fd = socket(AF_INET, SOCK_STREAM, 0);
#endif
    if (fd < 0)
	return NULL;

    val = 1;
   if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &val, sizeof(val)) < 0){
       	perror("setsockopt() :");
	return -1;
   }


    if (raw_connect(fd, addr, ntohs(portnum))) {
	ne_close(fd);
	return NULL;
    }

    return create_sock(fd);
}
Example #3
0
/* Closes given ne_socket */
int ne_sock_close(ne_socket *sock)
{
    int ret;
#ifdef NEON_SSL
    if (sock->ssl) {
	SSL_shutdown(sock->ssl);
	SSL_free(sock->ssl);
	if (sock->ssl_ctx)
	    SSL_CTX_free(sock->ssl_ctx);
    }
#endif
    ret = ne_close(sock->fd);
    ne_free(sock);
    return ret;
}
Example #4
0
int ne_sock_connect(ne_socket *sock,
                    const ne_inet_addr *addr, unsigned int port)
{
    int fd, ret;

#ifdef USE_GETADDRINFO
    /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
     * implementations do not set ai_socktype, e.g. RHL6.2. */
    fd = socket(addr->ai_family, SOCK_STREAM, addr->ai_protocol);
#else
    fd = socket(AF_INET, SOCK_STREAM, 0);
#endif
    if (fd < 0) {
        set_strerror(sock, ne_errno);
	return -1;
    }
    
#if !defined(NE_USE_POLL) && !defined(WIN32)
    if (fd > FD_SETSIZE) {
        ne_close(fd);
        set_error(sock, _("Socket descriptor number exceeds FD_SETSIZE"));
        return NE_SOCK_ERROR;
    }
#endif

#if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT) && defined(IPPROTO_TCP)
    { /* Disable the Nagle algorithm; better to add write buffering
       * instead of doing this. */
        int flag = 1;
        setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);
    }
#endif
    
    ret = connect_socket(sock, fd, addr, htons(port));
    if (ret == 0)
        sock->fd = fd;

    return ret;
}
Example #5
0
// Upon return no more I/O is possible. The stream is closed.
//
// If ne_close indicates a recoverable error, then the object is
// logged to the "degraded object log".
int mc_sync(DAL_Context* ctx) {
   ENTRY();

   ObjectStream* os         = MC_OS(ctx);
   ne_handle     handle     = MC_HANDLE(ctx);
   MC_Config*    config     = MC_CONFIG(ctx);
   MC_Context*   mc_context = MC_CONTEXT(ctx);
   
   if(! (os->flags & OSF_OPEN)) {
      LOG(LOG_ERR, "%s isn't open\n", os->url);
      errno = EINVAL;
      return -1;
   }

   // the result of close for a handle opened for reading is an
   // indicator of whether the data is degraded and, if so, which
   // block is corrupt or missing.
   int error_pattern = ne_close(handle);
   if(error_pattern > 0) {
      // Keeping the log message as well as writing to the degraded
      // object file for debugging purposes.
      LOG(LOG_INFO, "WARNING: Object %s degraded. Error pattern: 0x%x."
          " (N: %d, E: %d, Start: %d).\n",
          mc_context->path_template, error_pattern,
          config->n, config->e, mc_context->start_block);
      // we shouldn't need more then 512 bytes to hold the extra data
      // needed for rebuild
      char buf[MC_MAX_LOG_LEN];
      snprintf(buf, MC_MAX_LOG_LEN,
               MC_DEGRADED_LOG_FORMAT, mc_context->path_template,
               config->n, config->e,
               mc_context->start_block, error_pattern,
               MC_FH(ctx)->info.pre.repo->name,
               mc_context->pod, mc_context->cap);
      WAIT(&config->lock);
      // If the degraded log file has not already been opened, open it now.
      if(config->degraded_log_fd == -1) {
         config->degraded_log_fd =
            open_degraded_object_log(config->degraded_log_path);
         if(config->degraded_log_fd < 0) {
            LOG(LOG_ERR, "failed to open degraded log file\n");
         }
         else {
            // If we successfully opened it, then free the resources
            // used to store the path.
            free(config->degraded_log_path);
            config->degraded_log_path = NULL;
         }
      }

      if(write(config->degraded_log_fd, buf, strlen(buf))
         != strlen(buf)) {
         LOG(LOG_ERR, "Failed to write to degraded object log\n");
         // theoretically the data is still safe, so we can just log
         // and ignore the failure.
      }
      POST(&config->lock);
   }
   else if(error_pattern < 0) {
      // close the stream, a failed sync renders the ne_handle
      // invalid calling mc_close should prevent marfs from ever
      // trying to use it again.
      mc_close(ctx);
      os->flags |= OSF_ERRORS;
      LOG(LOG_ERR, "ne_close failed on %s", mc_context->path_template);
      return -1;
   }

   EXIT();
   return 0;
}
Example #6
0
int ne_sock_connect(ne_socket *sock,
                    const ne_inet_addr *addr, unsigned int port)
{
    int fd, ret;
    int type = SOCK_STREAM | sock_cloexec;

#if defined(RETRY_ON_EINVAL) && defined(SOCK_NONBLOCK) \
    && defined(USE_NONBLOCKING_CONNECT)
    /* If the SOCK_NONBLOCK flag is defined, and the retry-on-EINVAL
     * logic is enabled, and the socket has a configured timeout, then
     * also use the SOCK_NONBLOCK flag to save enabling O_NONBLOCK
     * later. */
    if (sock->cotimeout && sock_cloexec) {
        type |= SOCK_NONBLOCK;
    }
#endif

    /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
     * implementations do not set ai_socktype, e.g. RHL6.2. */
    fd = socket(ia_family(addr), type, ia_proto(addr));
#ifdef RETRY_ON_EINVAL
    /* Handle forwards compat for new glibc on an older kernels; clear
     * the sock_cloexec flag and retry the call: */
    if (fd < 0 && sock_cloexec && errno == EINVAL) {
        sock_cloexec = 0;
        fd = socket(ia_family(addr), SOCK_STREAM, ia_proto(addr));
    }
#endif
    if (fd < 0) {
        set_strerror(sock, ne_errno);
	return -1;
    }
    
#if !defined(NE_USE_POLL) && !defined(WIN32)
    if (fd > FD_SETSIZE) {
        ne_close(fd);
        set_error(sock, _("Socket descriptor number exceeds FD_SETSIZE"));
        return NE_SOCK_ERROR;
    }
#endif
   
#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) \
  && defined(FD_CLOEXEC)
    /* Set the FD_CLOEXEC bit for the new fd, if the socket was not
     * created with the CLOEXEC bit already set. */
    if (!sock_cloexec && (ret = fcntl(fd, F_GETFD)) >= 0) {
        fcntl(fd, F_SETFD, ret | FD_CLOEXEC);
        /* ignore failure; not a critical error. */
    }
#endif

    if (sock->laddr && (sock->laddr == &dummy_laddr || 
                        ia_family(sock->laddr) == ia_family(addr))) {
        ret = do_bind(fd, ia_family(addr), sock->laddr, sock->lport);
        if (ret < 0) {
            int errnum = errno;
            ne_close(fd);
            set_strerror(sock, errnum);
            return NE_SOCK_ERROR;
        }
    }

#if defined(HAVE_SETSOCKOPT) && (defined(TCP_NODELAY) || defined(WIN32))
    { /* Disable the Nagle algorithm. */
        int flag = 1;
        setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);
    }
#endif
    
    ret = connect_socket(sock, fd, addr, htons(port));
    if (ret == 0)
        sock->fd = fd;
    else
        ne_close(fd);

    return ret;
}