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);
}
Beispiel #2
0
/* 
 * 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;
}
Beispiel #3
0
/*
 * 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);
}
Beispiel #4
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
Beispiel #5
0
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;
}