Exemplo n.º 1
0
Arquivo: net.c Projeto: jdolan/quetoo
/**
 * @return A printable error string for the most recent OS-level network error.
 */
const char *Net_GetErrorString(void) {
#if defined(_WIN32)
	static char s[MAX_STRING_CHARS] = { 0 };
	
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
				   NULL, Net_GetError(),
				   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
				   s, sizeof(s), NULL);
	
	return s;
#else
	return strerror(Net_GetError());
#endif
}
Exemplo n.º 2
0
/**
 * @brief Send data to the specified TCP stream.
 */
_Bool Net_SendStream(int32_t sock, const void *data, size_t len) {
	mem_buf_t buf;
	byte buffer[MAX_MSG_SIZE];

	Mem_InitBuffer(&buf, buffer, sizeof(buffer));

	// write the packet length
	Net_WriteLong(&buf, (int32_t) len);

	// and copy the payload
	Net_WriteData(&buf, data, len);

	ssize_t sent = 0;
	while ((size_t) sent < buf.size) {
		const ssize_t s = send(sock, (void *)(buf.data + sent), buf.size - sent, 0);
		if (s == -1) {
			if (Net_GetError() != EWOULDBLOCK) {
				Com_Warn("%s\n", Net_GetErrorString());
				return false;
			}
		}
		sent += s;
	}

	return sent == (ssize_t) buf.size;
}
Exemplo n.º 3
0
/**
 * @brief Receive data from the specified TCP stream.
 */
_Bool Net_ReceiveStream(int32_t sock, mem_buf_t *buf) {

	buf->size = buf->read = 0;

	const ssize_t received = recv(sock, (void *) buf->data, buf->max_size, 0);
	if (received == -1) {

		if (Net_GetError() == EWOULDBLOCK) {
			return false;    // no data, don't crap our pants
		}

		Com_Warn("%s\n", Net_GetErrorString());
		return false;
	}

	buf->size = received;

	// check the packet length
	return Net_ReadLong(buf) > -1;
}
Exemplo n.º 4
0
/*
 * @brief
 */
_Bool Net_GetPacket(net_src_t source, net_addr_t *from, size_buf_t *message) {
	ssize_t ret;
	int32_t err;
	struct sockaddr_in from_addr;
	socklen_t from_len;
	char *s;

	if (Net_GetLocalPacket(source, from, message))
		return true;

	if (!ip_sockets[source])
		return false;

	from_len = sizeof(from_addr);

	ret = recvfrom(ip_sockets[source], (void *) message->data, message->max_size, 0,
			(struct sockaddr *) &from_addr, &from_len);

	Net_SockaddrToNetaddr(&from_addr, from);

	if (ret == -1) {
		err = Net_GetError();

		if (err == EWOULDBLOCK || err == ECONNREFUSED)
			return false; // not terribly abnormal

		s = source == NS_SERVER ? "server" : "client";
		Com_Warn("%s: %s from %s\n", s, Net_ErrorString(),
				Net_NetaddrToString(*from));
		return false;
	}

	if (ret == ((ssize_t) message->max_size)) {
		Com_Warn("Oversized packet from %s\n", Net_NetaddrToString(*from));
		return false;
	}

	message->size = (uint32_t) ret;
	return true;
}
Exemplo n.º 5
0
/**
 * @brief Establishes a TCP connection to the specified host.
 *
 * @param host The host to connect to. See Net_StringToNetaddr.
 */
int32_t Net_Connect(const char *host, struct timeval *timeout) {

	int32_t sock = Net_Socket(NA_STREAM, NULL, 0);

	struct sockaddr_in to;
	Net_StringToSockaddr(host, &to);

	if (connect(sock, (const struct sockaddr *) &to, sizeof(to)) == -1) {

		if (Net_GetError() == EINPROGRESS) {
			fd_set w_set;

			FD_ZERO(&w_set);
			FD_SET((uint32_t) sock, &w_set);

			if (select(sock + 1, NULL, &w_set, NULL, timeout) < 1) {
				Com_Error(ERROR_DROP, "%s\n", Net_GetErrorString());
			}

			int32_t error = -1;
			socklen_t len = sizeof(error);

			if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *) &error, &len) < 0) {
				Com_Error(ERROR_DROP, "%s\n", Net_GetErrorString());
			}

			if (error) {
				Com_Error(ERROR_DROP, "%s\n", strerror(error));
			}
		} else {
			Com_Error(ERROR_DROP, "%s\n", Net_GetErrorString());
		}
	}

	return sock;
}
Exemplo n.º 6
0
/*
 * @brief
 */
static const char *Net_ErrorString(void) {
	const int32_t code = Net_GetError();
	return strerror(code);
}
Exemplo n.º 7
0
/*
 * @return A printable error string for the most recent OS-level network error.
 */
const char *Net_GetErrorString(void) {
	return strerror(Net_GetError());
}