int rain_rehydrate_noalloc(struct rain_encoding_s *enc, uint8_t **data, uint8_t **coding, int *erasures) { assert(data != NULL); assert(coding != NULL); assert(enc != NULL); if (!is_recoverable(enc, erasures)) return 0; return do_rehydrate(enc, data, coding, erasures); }
/* * Write len bytes from buff to the client. Kick him on network errors. * Return the number of bytes written and -1 on error. * Assert Class: 2 * Potential problems: Any usage of errno is bad in a threaded application. */ int sock_write_bytes_or_kick(SOCKET sockfd, connection_t * clicon, const char *buff, const int len) { int res, err; if (!sock_valid(sockfd)) { xa_debug(1, "ERROR: sock_write_bytes_or_kick() called with invalid socket"); return -1; } else if (!clicon) { xa_debug(1, "ERROR: sock_write_bytes_or_kick() called with NULL client"); return -1; } else if (!buff) { xa_debug(1, "ERROR: sock_write_bytes_or_kick() called with NULL data"); return -1; } else if (len <= 0) { xa_debug(1, "ERROR: sock_write_bytes_or_kick() called with invalid length"); return -1; } errno = 666; res = sock_write_bytes(sockfd, buff, len); err = errno; if (res < 0) { xa_debug(4, "DEBUG: sock_write_bytes_or_kick: %d err [%d]", res, err); if (!is_recoverable(errno)) { kick_connection(clicon, "Client signed off"); return -1; } } return res; }
/* * Write a string to a socket. * Return 1 if all bytes where successfully written, and 0 if not. * Assert Class: 2 */ int sock_write_string(SOCKET sockfd, const char *buff) { int write_bytes = 0, res = 0, len = ice_strlen(buff); if (!sock_valid(sockfd)) { fprintf(stderr, "ERROR: sock_write_string() called with invalid socket\n"); return -1; } else if (!buff) { fprintf(stderr, "ERROR: sock_write_string() called with NULL format\n"); return -1; } /* * Never use send() to sockets 0 or 1 in Win32. */ if (sockfd == 1 || sockfd == 0) { if (running == SERVER_RUNNING) { write_bytes = fprintf(stdout, "%s", buff); fflush(stdout); } } else { while (write_bytes < len) { res = send(sockfd, &buff[write_bytes], len - write_bytes, 0); if (res < 0 && !is_recoverable(errno)) return 0; if (res > 0) write_bytes += res; else my_sleep(30000); } } return (write_bytes == len ? 1 : 0); }
/* * Connect to hostname on specified port and return the created socket. * Assert Class: 3 */ SOCKET sock_connect_wto(const char *hostname, const int port, const int timeout) { SOCKET sockfd; struct sockaddr_in sin, server; struct hostent *host; struct hostent hostinfo; char buf[BUFSIZE]; int error; if (!hostname || !hostname[0]) { write_log(LOG_DEFAULT, "ERROR: sock_connect() called with NULL or empty hostname"); return INVALID_SOCKET; } else if (port <= 0) { write_log(LOG_DEFAULT, "ERROR: sock_connect() called with invalid port number"); return INVALID_SOCKET; } sockfd = sock_socket(AF_INET, SOCK_STREAM, 0); if (sockfd == INVALID_SOCKET) { sock_close(sockfd); return INVALID_SOCKET; } if (info.myhostname != NULL) { struct sockaddr_in localsin; memset(&localsin, 0, sizeof (struct sockaddr_in)); xa_debug(2, "DEBUG: Trying to bind to %s", info.myhostname); localsin.sin_addr = localaddr; localsin.sin_family = AF_INET; localsin.sin_port = 0; if (bind (sockfd, (struct sockaddr *) &localsin, sizeof (localsin)) == SOCKET_ERROR) { xa_debug(2, "DEBUG: Unable to bind", info.myhostname); write_log(LOG_DEFAULT, "ERROR: Bind to local address %s failed", info.myhostname); sock_close(sockfd); return INVALID_SOCKET; } } memset(&sin, 0, sizeof (sin)); memset(&server, 0, sizeof (struct sockaddr_in)); if (isdigit((int) hostname[0]) && isdigit((int) hostname[ice_strlen(hostname) - 1])) { if (inet_aton(hostname, (struct in_addr *) &sin.sin_addr) == 0) { write_log(LOG_DEFAULT, "ERROR: Invalid ip number %s", hostname); sock_close(sockfd); return INVALID_SOCKET; } memcpy(&server.sin_addr, &sin.sin_addr, sizeof (sin)); } else { host = ice_gethostbyname(hostname, &hostinfo, buf, BUFSIZE, &error); if (host == NULL) { xa_debug(1, "DEBUG: gethostbyname %s failed", hostname); sock_close(sockfd); ice_clean_hostent(); return INVALID_SOCKET; } memcpy(&server.sin_addr, host->h_addr, host->h_length); ice_clean_hostent(); } server.sin_family = AF_INET; server.sin_port = htons(port); { char buf[50]; makeasciihost(&server.sin_addr, buf); xa_debug(1, "Trying to connect to %s:%d", buf, port); } if (timeout > 0) { fd_set wfds; struct timeval tv; int retval; int val; socklen_t valsize = sizeof (int); xa_debug(3, "DEBUG: sock_connect(): doing a connection w/ timeout"); FD_ZERO(&wfds); FD_SET(sockfd, &wfds); tv.tv_sec = timeout; tv.tv_usec = 0; sock_set_blocking(sockfd, SOCK_NONBLOCK); retval = connect(sockfd, (struct sockaddr *) &server, sizeof (server)); if (retval == 0) { xa_debug(3, "DEBUG: sock_connect(): non blocking connect returned 0!"); sock_set_blocking(sockfd, SOCK_BLOCK); return sockfd; } else { #ifdef _WIN32 if (WSAGetLastError() == WSAEINPROGRESS) { #else if (!is_recoverable(errno)) { #endif xa_debug(3, "DEBUG: sock_connect(): connect didn't return EINPROGRESS!, was: %d", errno); sock_close(sockfd); return SOCKET_ERROR; } } if (select(sockfd + 1, NULL, &wfds, NULL, &tv)) { retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *) &val, (socklen_t *) & valsize); if ((retval == 0) && (val == 0)) { sock_set_blocking(sockfd, SOCK_BLOCK); return sockfd; } else { xa_debug(3, "DEBUG: sock_connect(): getsockopt returned %i, val = %i, valsize = %i, errno = %i!", retval, val, valsize, errno); sock_close(sockfd); return SOCKET_ERROR; } } else { xa_debug(3, "DEBUG: sock_connect(): select returned 0"); sock_close(sockfd); return SOCKET_ERROR; } } else { if (connect
connection_t * get_connection (sock_t *sock) { int sockfd; socklen_t sin_len; connection_t *con; fd_set rfds; struct timeval tv; int i, maxport = 0; struct sockaddr_in *sin = (struct sockaddr_in *)nmalloc(sizeof(struct sockaddr_in)); if (!sin) { write_log (LOG_DEFAULT, "WARNING: Weird stuff in get_connection. nmalloc returned NULL sin"); return NULL; } /* setup sockaddr structure */ sin_len = sizeof(struct sockaddr_in); memset(sin, 0, sin_len); /* try to accept a connection */ FD_ZERO(&rfds); for (i = 0; i < MAXLISTEN; i++) { if (sock_valid (sock[i])) { FD_SET(sock[i], &rfds); if (sock[i] > maxport) maxport = sock[i]; } } maxport += 1; tv.tv_sec = 0; tv.tv_usec = 30000; if (select(maxport, &rfds, NULL, NULL, &tv) > 0) { for (i = 0; i < MAXLISTEN; i++) { if (sock_valid (sock[i]) && FD_ISSET(sock[i], &rfds)) break; } } else { nfree(sin); return NULL; } sockfd = sock_accept(sock[i], (struct sockaddr *)sin, &sin_len); if (sockfd >= 0) { con = create_connection(); if (!sin) { xa_debug (1, "ERROR: NULL sockaddr struct, wft???"); return NULL; } con->host = create_malloced_ascii_host(&(sin->sin_addr)); con->sock = sockfd; con->sin = sin; con->sinlen = sin_len; xa_debug (2, "DEBUG: Getting new connection on socket %d from host %s", sockfd, con->host ? con->host : "(null)"); con->hostname = NULL; con->headervars = NULL; con->id = new_id (); con->connect_time = get_time (); #ifdef HAVE_LIBWRAP if (!sock_check_libwrap(sockfd, unknown_connection_e)) { kick_not_connected (con, "Access Denied (tcp wrappers) [generic connection]"); return NULL; } #endif return con; } if (!is_recoverable (errno)) xa_debug (1, "WARNING: accept() failed with on socket %d, max: %d, [%d:%s]", sock[i], maxport, errno, strerror(errno)); nfree (sin); return NULL; }