/* 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; }
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); }
/* 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; }
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; }
// 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; }
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; }