src/network/core/udp.c
branchcustombridgeheads
changeset 5648 1608018c5ff2
parent 5643 3778051e8095
equal deleted inserted replaced
5647:cbde85c8c878 5648:1608018c5ff2
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 #ifdef ENABLE_NETWORK
     3 #ifdef ENABLE_NETWORK
     4 
     4 
     5 #include "../../stdafx.h"
     5 #include "../../stdafx.h"
     6 #include "../../date.h"
       
     7 #include "../../debug.h"
     6 #include "../../debug.h"
     8 #include "../../macros.h"
     7 #include "../../macros.h"
     9 #include "../../newgrf_config.h"
       
    10 
       
    11 #include "os_abstraction.h"
       
    12 #include "config.h"
       
    13 #include "game.h"
       
    14 #include "packet.h"
     8 #include "packet.h"
    15 #include "udp.h"
     9 #include "udp.h"
    16 
    10 
    17 /**
    11 /**
    18  * @file udp.c Basic functions to receive and send UDP packets.
    12  * @file udp.c Basic functions to receive and send UDP packets.
    19  */
    13  */
    20 
       
    21 /**
       
    22  * Send a packet over UDP
       
    23  * @param udp  the socket to send over
       
    24  * @param p    the packet to send
       
    25  * @param recv the receiver (target) of the packet
       
    26  */
       
    27 void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv)
       
    28 {
       
    29 	int res;
       
    30 
       
    31 	NetworkSend_FillPacketSize(p);
       
    32 
       
    33 	/* Send the buffer */
       
    34 	res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
       
    35 
       
    36 	/* Check for any errors, but ignore it otherwise */
       
    37 	if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
       
    38 }
       
    39 
    14 
    40 /**
    15 /**
    41  * Start listening on the given host and port.
    16  * Start listening on the given host and port.
    42  * @param udp       the place where the (references to the) UDP are stored
    17  * @param udp       the place where the (references to the) UDP are stored
    43  * @param host      the host (ip) to listen on
    18  * @param host      the host (ip) to listen on
    44  * @param port      the port to listen on
    19  * @param port      the port to listen on
    45  * @param broadcast whether to allow broadcast sending/receiving
    20  * @param broadcast whether to allow broadcast sending/receiving
    46  * @return true if the listening succeeded
    21  * @return true if the listening succeeded
    47  */
    22  */
    48 bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast)
    23 bool NetworkUDPListen(SOCKET *udp, const uint32 host, const uint16 port, const bool broadcast)
    49 {
    24 {
    50 	struct sockaddr_in sin;
    25 	struct sockaddr_in sin;
    51 
    26 
    52 	/* Make sure socket is closed */
    27 	/* Make sure socket is closed */
    53 	closesocket(*udp);
    28 	NetworkUDPClose(udp);
    54 
    29 
    55 	*udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    30 	*udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    56 	if (*udp == INVALID_SOCKET) {
    31 	if (*udp == INVALID_SOCKET) {
    57 		DEBUG(net, 0, "[udp] failed to start UDP listener");
    32 		DEBUG(net, 0, "[udp] failed to start UDP listener");
    58 		return false;
    33 		return false;
    90 
    65 
    91 	return true;
    66 	return true;
    92 }
    67 }
    93 
    68 
    94 /**
    69 /**
       
    70  * Close the given UDP socket
       
    71  * @param udp the socket to close
       
    72  */
       
    73 void NetworkUDPClose(SOCKET *udp)
       
    74 {
       
    75 	if (*udp == INVALID_SOCKET) return;
       
    76 
       
    77 	closesocket(*udp);
       
    78 	*udp = INVALID_SOCKET;
       
    79 }
       
    80 
       
    81 
       
    82 /**
       
    83  * Send a packet over UDP
       
    84  * @param udp  the socket to send over
       
    85  * @param p    the packet to send
       
    86  * @param recv the receiver (target) of the packet
       
    87  */
       
    88 void NetworkSendUDP_Packet(const SOCKET udp, Packet *p, const struct sockaddr_in *recv)
       
    89 {
       
    90 	int res;
       
    91 
       
    92 	NetworkSend_FillPacketSize(p);
       
    93 
       
    94 	/* Send the buffer */
       
    95 	res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
       
    96 
       
    97 	/* Check for any errors, but ignore it otherwise */
       
    98 	if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
       
    99 }
       
   100 
       
   101 /**
    95  * Receive a packet at UDP level
   102  * Receive a packet at UDP level
    96  * @param udp the socket to receive the packet on
   103  * @param udp the socket to receive the packet on
    97  */
   104  */
    98 void NetworkUDPReceive(SOCKET udp)
   105 void NetworkUDPReceive(const SOCKET udp)
    99 {
   106 {
   100 	struct sockaddr_in client_addr;
   107 	struct sockaddr_in client_addr;
   101 	socklen_t client_len;
   108 	socklen_t client_len;
   102 	int nbytes;
   109 	int nbytes;
   103 	Packet p;
   110 	Packet p;
   107 	client_len = sizeof(client_addr);
   114 	client_len = sizeof(client_addr);
   108 
   115 
   109 	/* Try to receive anything */
   116 	/* Try to receive anything */
   110 	nbytes = recvfrom(udp, p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
   117 	nbytes = recvfrom(udp, p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
   111 
   118 
   112 	/* We got some bytes for the base header of the packet.
   119 	/* We got some bytes for the base header of the packet. */
   113 	 * Assume we received the whole packet. */
       
   114 	if (nbytes > 2) {
   120 	if (nbytes > 2) {
   115 		NetworkRecv_ReadPacketSize(&p);
   121 		NetworkRecv_ReadPacketSize(&p);
       
   122 
       
   123 		/* If the size does not match the packet must be corrupted.
       
   124 		 * Otherwise it will be marked as corrupted later on. */
       
   125 		if (nbytes != p.size) {
       
   126 			DEBUG(net, 1, "received a packet with mismatching size from %s:%d",
       
   127 					inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
       
   128 
       
   129 			return;
       
   130 		}
   116 
   131 
   117 		/* Put the position on the right place */
   132 		/* Put the position on the right place */
   118 		p.pos = 2;
   133 		p.pos = 2;
   119 		p.next = NULL;
   134 		p.next = NULL;
   120 
   135 
   121 		/* Handle the packet */
   136 		/* Handle the packet */
   122 		NetworkHandleUDPPacket(&p, &client_addr);
   137 		NetworkHandleUDPPacket(udp, &p, &client_addr);
   123 	}
   138 	}
   124 }
   139 }
   125 
   140 
   126 
   141 
   127 /**
   142 /**
   166 	/*
   181 	/*
   167 	 *              Please observe the order.
   182 	 *              Please observe the order.
   168 	 * The parts must be read in the same order as they are sent!
   183 	 * The parts must be read in the same order as they are sent!
   169 	 */
   184 	 */
   170 
   185 
       
   186 	/* Update the documentation in udp.h on changes
       
   187 	 * to the NetworkGameInfo wire-protocol! */
   171 
   188 
   172 	/* NETWORK_GAME_INFO_VERSION = 4 */
   189 	/* NETWORK_GAME_INFO_VERSION = 4 */
   173 	{
   190 	{
   174 		/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
   191 		/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
   175 		 * the GRFs that are needed, i.e. the ones that the server has
   192 		 * the GRFs that are needed, i.e. the ones that the server has
   226 
   243 
   227 	/*
   244 	/*
   228 	 *              Please observe the order.
   245 	 *              Please observe the order.
   229 	 * The parts must be read in the same order as they are sent!
   246 	 * The parts must be read in the same order as they are sent!
   230 	 */
   247 	 */
       
   248 
       
   249 	/* Update the documentation in udp.h on changes
       
   250 	 * to the NetworkGameInfo wire-protocol! */
   231 
   251 
   232 	switch (info->game_info_version) {
   252 	switch (info->game_info_version) {
   233 		case 4: {
   253 		case 4: {
   234 			GRFConfig *c, **dst = &info->grfconfig;
   254 			GRFConfig *c, **dst = &info->grfconfig;
   235 			uint i;
   255 			uint i;