Exemple #1
0
/**
 * @brief Send the servers list to the specified client address.
 */
static void Ms_GetServers(struct sockaddr_in *from) {
	mem_buf_t buf;
	byte buffer[0xffff];

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

	const char *servers = "\xFF\xFF\xFF\xFF" "servers ";
	Mem_WriteBuffer(&buf, servers, strlen(servers));

	uint32_t i = 0;
	GList *s = ms_servers;
	while (s) {
		const ms_server_t *server = (ms_server_t *) s->data;
		if (server->validated) {
			Mem_WriteBuffer(&buf, &server->addr.sin_addr, sizeof(server->addr.sin_addr));
			Mem_WriteBuffer(&buf, &server->addr.sin_port, sizeof(server->addr.sin_port));
			i++;
		}
		s = s->next;
	}

	if ((sendto(ms_sock, buf.data, buf.size, 0, (struct sockaddr *) from, sizeof(*from))) == -1) {
		Com_Warn("%s: %s\n", atos(from), strerror(errno));
	} else {
		Com_Verbose("Sent %d servers to %s\n", i, atos(from));
	}
}
Exemple #2
0
/*
 * @brief Sends an out-of-band datagram
 */
void Netchan_OutOfBand(int32_t sock, const net_addr_t *addr, const void *data, size_t len) {
	mem_buf_t send;
	byte send_buffer[MAX_MSG_SIZE];

	// write the packet header
	Mem_InitBuffer(&send, send_buffer, sizeof(send_buffer));

	Net_WriteLong(&send, -1); // -1 sequence means out of band
	Mem_WriteBuffer(&send, data, len);

	// send the datagram
	Net_SendDatagram(sock, addr, send.data, send.size);
}
Exemple #3
0
/*
 * @brief Tries to send an unreliable message to a connection, and handles the
 * transmission / retransmission of the reliable messages.
 *
 * A 0 size will still generate a packet and deal with the reliable messages.
 */
void Netchan_Transmit(net_chan_t *chan, byte *data, size_t len) {
	mem_buf_t send;
	byte send_buffer[MAX_MSG_SIZE];

	// check for message overflow
	if (chan->message.overflowed) {
		chan->fatal_error = true;
		Com_Print("%s:Outgoing message overflow\n", Net_NetaddrToString(&chan->remote_address));
		return;
	}

	const _Bool send_reliable = Netchan_NeedReliable(chan);

	if (!chan->reliable_size && chan->message.size) {
		memcpy(chan->reliable_buffer, chan->message_buffer, chan->message.size);
		chan->reliable_size = chan->message.size;
		chan->message.size = 0;
		chan->reliable_sequence ^= 1;
	}

	// write the packet header
	Mem_InitBuffer(&send, send_buffer, sizeof(send_buffer));

	const uint32_t w1 = (chan->outgoing_sequence & ~(1 << 31)) | (send_reliable << 31);
	const uint32_t w2 = (chan->incoming_sequence & ~(1 << 31)) | (chan->incoming_reliable_sequence
			<< 31);

	chan->outgoing_sequence++;
	chan->last_sent = quake2world.time;

	Net_WriteLong(&send, w1);
	Net_WriteLong(&send, w2);

	// send the qport if we are a client
	if (chan->source == NS_UDP_CLIENT)
		Net_WriteByte(&send, chan->qport);

	// copy the reliable message to the packet first
	if (send_reliable) {
		Mem_WriteBuffer(&send, chan->reliable_buffer, chan->reliable_size);
		chan->last_reliable_sequence = chan->outgoing_sequence;
	}

	// add the unreliable part if space is available
	if (send.max_size - send.size >= len)
		Mem_WriteBuffer(&send, data, len);
	else
		Com_Warn("Netchan_Transmit: dumped unreliable\n");

	// send the datagram
	Net_SendDatagram(chan->source, &chan->remote_address, send.data, send.size);

	if (net_showpackets->value) {
		if (send_reliable)
			Com_Print("Send %u bytes: s=%i reliable=%i ack=%i rack=%i\n", (uint32_t) send.size,
					chan->outgoing_sequence - 1, chan->reliable_sequence, chan->incoming_sequence,
					chan->incoming_reliable_sequence);
		else
			Com_Print("Send %u bytes : s=%i ack=%i rack=%i\n", (uint32_t) send.size,
					chan->outgoing_sequence - 1, chan->incoming_sequence,
					chan->incoming_reliable_sequence);
	}
}