src/network/core/tcp.c
author celestar
Thu, 11 Jan 2007 13:16:26 +0000
branchcustombridgeheads
changeset 5648 1608018c5ff2
parent 5643 3778051e8095
permissions -rw-r--r--
(svn r8059) [cbh] - Sync with r7788:8032 from trunk
5642
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     1
/* $Id$ */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     2
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     3
#ifdef ENABLE_NETWORK
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     4
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     5
#include "../../stdafx.h"
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     6
#include "../../debug.h"
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     7
#include "../../openttd.h"
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
     8
#include "../../variables.h"
5643
3778051e8095 (svn r7790) [cbh] -Sync: execute the same script for /branches/custombridgeheads as was done for /trunk in r7759.
rubidium
parents: 5642
diff changeset
     9
#include "table/strings.h"
5642
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    10
#include "../../functions.h"
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    11
5648
1608018c5ff2 (svn r8059) [cbh] - Sync with r7788:8032 from trunk
celestar
parents: 5643
diff changeset
    12
#include "../network_data.h"
5642
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    13
#include "packet.h"
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    14
#include "tcp.h"
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    15
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    16
/**
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    17
 * @file tcp.c Basic functions to receive and send TCP packets.
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    18
 */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    19
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    20
/**
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    21
 * Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    22
 *  A socket can make errors. When that happens this handles what to do.
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    23
 * For clients: close connection and drop back to main-menu
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    24
 * For servers: close connection and that is it
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    25
 * @param cs the client to close the connection of
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    26
 * @return the new status
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    27
 */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    28
NetworkRecvStatus CloseConnection(NetworkClientState *cs)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    29
{
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    30
	NetworkCloseClient(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    31
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    32
	/* Clients drop back to the main menu */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    33
	if (!_network_server && _networking) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    34
		_switch_mode = SM_MENU;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    35
		_networking = false;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    36
		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    37
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    38
		return NETWORK_RECV_STATUS_CONN_LOST;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    39
	}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    40
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    41
	return NETWORK_RECV_STATUS_OKAY;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    42
}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    43
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    44
/**
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    45
 * Whether the client has quit or not (used in packet.c)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    46
 * @param cs the client to check
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    47
 * @return true if the client has quit
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    48
 */
5648
1608018c5ff2 (svn r8059) [cbh] - Sync with r7788:8032 from trunk
celestar
parents: 5643
diff changeset
    49
bool HasClientQuit(const NetworkClientState *cs)
5642
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    50
{
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    51
	return cs->has_quit;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    52
}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    53
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    54
/**
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    55
 * This function puts the packet in the send-queue and it is send as
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    56
 * soon as possible. This is the next tick, or maybe one tick later
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    57
 * if the OS-network-buffer is full)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    58
 * @param packet the packet to send
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    59
 * @param cs     the client to send to
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    60
 */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    61
void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    62
{
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    63
	Packet *p;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    64
	assert(packet != NULL);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    65
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    66
	packet->pos = 0;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    67
	packet->next = NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    68
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    69
	NetworkSend_FillPacketSize(packet);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    70
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    71
	/* Locate last packet buffered for the client */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    72
	p = cs->packet_queue;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    73
	if (p == NULL) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    74
		/* No packets yet */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    75
		cs->packet_queue = packet;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    76
	} else {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    77
		/* Skip to the last packet */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    78
		while (p->next != NULL) p = p->next;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    79
		p->next = packet;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    80
	}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    81
}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    82
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    83
/**
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    84
 * Sends all the buffered packets out for this client. It stops when:
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    85
 *   1) all packets are send (queue is empty)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    86
 *   2) the OS reports back that it can not send any more
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    87
 *      data right now (full network-buffer, it happens ;))
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    88
 *   3) sending took too long
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    89
 * @param cs the client to send the packets for
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    90
 */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    91
bool NetworkSend_Packets(NetworkClientState *cs)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    92
{
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    93
	ssize_t res;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    94
	Packet *p;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    95
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    96
	/* We can not write to this socket!! */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    97
	if (!cs->writable) return false;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    98
	if (cs->socket == INVALID_SOCKET) return false;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
    99
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   100
	p = cs->packet_queue;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   101
	while (p != NULL) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   102
		res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   103
		if (res == -1) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   104
			int err = GET_LAST_ERROR();
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   105
			if (err != EWOULDBLOCK) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   106
				/* Something went wrong.. close client! */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   107
				DEBUG(net, 0, "send failed with error %d", err);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   108
				CloseConnection(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   109
				return false;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   110
			}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   111
			return true;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   112
		}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   113
		if (res == 0) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   114
			/* Client/server has left us :( */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   115
			CloseConnection(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   116
			return false;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   117
		}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   118
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   119
		p->pos += res;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   120
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   121
		/* Is this packet sent? */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   122
		if (p->pos == p->size) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   123
			/* Go to the next packet */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   124
			cs->packet_queue = p->next;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   125
			free(p);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   126
			p = cs->packet_queue;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   127
		} else {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   128
			return true;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   129
		}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   130
	}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   131
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   132
	return true;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   133
}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   134
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   135
/**
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   136
 * Receives a packet for the given client
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   137
 * @param cs     the client to (try to) receive a packet for
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   138
 * @param status the variable to store the status into
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   139
 * @return the received packet (or NULL when it didn't receive one)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   140
 */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   141
Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   142
{
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   143
	ssize_t res;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   144
	Packet *p;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   145
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   146
	*status = NETWORK_RECV_STATUS_OKAY;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   147
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   148
	if (cs->socket == INVALID_SOCKET) return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   149
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   150
	if (cs->packet_recv == NULL) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   151
		cs->packet_recv = malloc(sizeof(Packet));
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   152
		if (cs->packet_recv == NULL) error("Failed to allocate packet");
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   153
		/* Set pos to zero! */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   154
		cs->packet_recv->pos = 0;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   155
		cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   156
	}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   157
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   158
	p = cs->packet_recv;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   159
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   160
	/* Read packet size */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   161
	if (p->pos < sizeof(PacketSize)) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   162
		while (p->pos < sizeof(PacketSize)) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   163
			/* Read the size of the packet */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   164
			res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   165
			if (res == -1) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   166
				int err = GET_LAST_ERROR();
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   167
				if (err != EWOULDBLOCK) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   168
					/* Something went wrong... (104 is connection reset by peer) */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   169
					if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   170
					*status = CloseConnection(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   171
					return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   172
				}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   173
				/* Connection would block, so stop for now */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   174
				return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   175
			}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   176
			if (res == 0) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   177
				/* Client/server has left */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   178
				*status = CloseConnection(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   179
				return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   180
			}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   181
			p->pos += res;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   182
		}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   183
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   184
		NetworkRecv_ReadPacketSize(p);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   185
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   186
		if (p->size > SEND_MTU) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   187
			*status = CloseConnection(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   188
			return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   189
		}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   190
	}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   191
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   192
	/* Read rest of packet */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   193
	while (p->pos < p->size) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   194
		res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   195
		if (res == -1) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   196
			int err = GET_LAST_ERROR();
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   197
			if (err != EWOULDBLOCK) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   198
				/* Something went wrong... (104 is connection reset by peer) */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   199
				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   200
				*status = CloseConnection(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   201
				return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   202
			}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   203
			/* Connection would block */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   204
			return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   205
		}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   206
		if (res == 0) {
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   207
			/* Client/server has left */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   208
			*status = CloseConnection(cs);
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   209
			return NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   210
		}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   211
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   212
		p->pos += res;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   213
	}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   214
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   215
	/* We have a complete packet, return it! */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   216
	p->pos = 2;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   217
	p->next = NULL; // Should not be needed, but who knows...
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   218
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   219
	/* Prepare for receiving a new packet */
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   220
	cs->packet_recv = NULL;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   221
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   222
	return p;
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   223
}
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   224
bfa6074e2833 (svn r7789) [cbh] - Sync with r7720:7758 from trunk
celestar
parents:
diff changeset
   225
#endif /* ENABLE_NETWORK */