network_udp.c
changeset 764 7e1e17b7c7d4
parent 738 b96ab9e63d22
child 765 18104986675d
equal deleted inserted replaced
763:ced9fcae239d 764:7e1e17b7c7d4
     2 #include "network_data.h"
     2 #include "network_data.h"
     3 
     3 
     4 #ifdef ENABLE_NETWORK
     4 #ifdef ENABLE_NETWORK
     5 
     5 
     6 #include "network_gamelist.h"
     6 #include "network_gamelist.h"
       
     7 #include "network_udp.h"
     7 
     8 
     8 extern void UpdateNetworkGameWindow(bool unselect);
     9 extern void UpdateNetworkGameWindow(bool unselect);
     9 extern void NetworkPopulateCompanyInfo(void);
    10 extern void NetworkPopulateCompanyInfo(void);
    10 
    11 
    11 //
    12 //
    18 	PACKET_UDP_CLIENT_FIND_SERVER,
    19 	PACKET_UDP_CLIENT_FIND_SERVER,
    19 	PACKET_UDP_SERVER_RESPONSE,
    20 	PACKET_UDP_SERVER_RESPONSE,
    20 	PACKET_UDP_CLIENT_DETAIL_INFO,
    21 	PACKET_UDP_CLIENT_DETAIL_INFO,
    21 	PACKET_UDP_SERVER_DETAIL_INFO, // Is not used in OpenTTD itself, only for external querying
    22 	PACKET_UDP_SERVER_DETAIL_INFO, // Is not used in OpenTTD itself, only for external querying
    22 	PACKET_UDP_SERVER_REGISTER, // Packet to register itself to the master server
    23 	PACKET_UDP_SERVER_REGISTER, // Packet to register itself to the master server
       
    24 	PACKET_UDP_MASTER_ACK_REGISTER, // Packet indicating registration has succedeed
       
    25 	PACKET_UDP_CLIENT_GET_LIST, // Request for serverlist from master server
       
    26 	PACKET_UDP_MASTER_RESPONSE_LIST, // Response from master server with server ip's + port's
    23 	PACKET_UDP_END
    27 	PACKET_UDP_END
    24 } PacketUDPType;
    28 } PacketUDPType;
    25 
    29 
    26 static SOCKET _udp_server_socket; // udp server socket
    30 enum {
       
    31 	ADVERTISE_NORMAL_INTERVAL = 450,	// interval between advertising in days
       
    32 	ADVERTISE_RETRY_INTERVAL = 5,			// readvertise when no response after this amount of days
       
    33 	ADVERTISE_RETRY_TIMES = 3					// give up readvertising after this much failed retries
       
    34 };
    27 
    35 
    28 #define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
    36 #define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
    29 void NetworkSendUDP_Packet(Packet *p, struct sockaddr_in *recv);
    37 void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv);
    30 
    38 
    31 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
    39 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
    32 {
    40 {
    33 	Packet *packet;
    41 	Packet *packet;
    34 	// Just a fail-safe.. should never happen
    42 	// Just a fail-safe.. should never happen
    56 	NetworkSend_uint16(packet, _network_game_info.map_height);
    64 	NetworkSend_uint16(packet, _network_game_info.map_height);
    57 	NetworkSend_uint8 (packet, _network_game_info.map_set);
    65 	NetworkSend_uint8 (packet, _network_game_info.map_set);
    58 	NetworkSend_uint8 (packet, _network_game_info.dedicated);
    66 	NetworkSend_uint8 (packet, _network_game_info.dedicated);
    59 
    67 
    60 	// Let the client know that we are here
    68 	// Let the client know that we are here
    61 	NetworkSendUDP_Packet(packet, client_addr);
    69 	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
    62 
    70 
    63 	free(packet);
    71 	free(packet);
    64 
    72 
    65 	DEBUG(net, 2)("[NET][UDP] Queried from %s", inet_ntoa(client_addr->sin_addr));
    73 	DEBUG(net, 2)("[NET][UDP] Queried from %s", inet_ntoa(client_addr->sin_addr));
    66 }
    74 }
    73 	// Just a fail-safe.. should never happen
    81 	// Just a fail-safe.. should never happen
    74 	if (_network_udp_server)
    82 	if (_network_udp_server)
    75 		return;
    83 		return;
    76 
    84 
    77 	game_info_version = NetworkRecv_uint8(p);
    85 	game_info_version = NetworkRecv_uint8(p);
       
    86 
       
    87 
       
    88 	DEBUG(net, 6)("[NET][UDP] Server response from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
    78 
    89 
    79 	// Find next item
    90 	// Find next item
    80 	item = NetworkGameListAddItem(inet_addr(inet_ntoa(client_addr->sin_addr)), ntohs(client_addr->sin_port));
    91 	item = NetworkGameListAddItem(inet_addr(inet_ntoa(client_addr->sin_addr)), ntohs(client_addr->sin_port));
    81 
    92 
    82 	if (game_info_version == 1) {
    93 	if (game_info_version == 1) {
   203 	}
   214 	}
   204 
   215 
   205 	/* Indicates end of client list */
   216 	/* Indicates end of client list */
   206 	NetworkSend_uint8(packet, 0);
   217 	NetworkSend_uint8(packet, 0);
   207 
   218 
   208 	NetworkSendUDP_Packet(packet, client_addr);
   219 	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
   209 
   220 
   210 	free(packet);
   221 	free(packet);
       
   222 }
       
   223 
       
   224 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST) {
       
   225 	int i;
       
   226 	struct in_addr ip;
       
   227 	uint16 port;
       
   228 	uint8 ver;
       
   229 
       
   230 	/* packet begins with the protocol version (uint8)
       
   231 	 * then an uint16 which indicates how many
       
   232 	 * ip:port pairs are in this packet, after that
       
   233 	 * an uint32 (ip) and an uint16 (port) for each pair
       
   234 	 */
       
   235 
       
   236 	ver = NetworkRecv_uint8(p);
       
   237 
       
   238 	if (ver == 1) {
       
   239 		for (i = NetworkRecv_uint16(p); i != 0 ; i--) {
       
   240 			ip.s_addr = TO_LE32(NetworkRecv_uint32(p));
       
   241 			port = NetworkRecv_uint16(p);
       
   242 			NetworkUDPQueryServer(inet_ntoa(ip), port);
       
   243 		}
       
   244 	}
       
   245 }
       
   246 
       
   247 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER) {
       
   248 	_network_advertise_retries = 0;
       
   249 	DEBUG(net, 2)("[NET] We are advertised on the master-server!");
   211 }
   250 }
   212 
   251 
   213 
   252 
   214 // The layout for the receive-functions by UDP
   253 // The layout for the receive-functions by UDP
   215 typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
   254 typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
   218 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
   257 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
   219 	RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
   258 	RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
   220 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
   259 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
   221 	NULL,
   260 	NULL,
   222 	NULL,
   261 	NULL,
       
   262 	RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER),
       
   263 	NULL,
       
   264 	RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST)
   223 };
   265 };
       
   266 
   224 
   267 
   225 // If this fails, check the array above with network_data.h
   268 // If this fails, check the array above with network_data.h
   226 assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
   269 assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
   227 
   270 
   228 
   271 
   239 	}
   282 	}
   240 }
   283 }
   241 
   284 
   242 
   285 
   243 // Send a packet over UDP
   286 // Send a packet over UDP
   244 void NetworkSendUDP_Packet(Packet *p, struct sockaddr_in *recv)
   287 void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv)
   245 {
   288 {
   246 	SOCKET udp;
       
   247 	int res;
   289 	int res;
   248 
       
   249 	// Find the correct socket
       
   250 	if (_network_udp_server)
       
   251 		udp = _udp_server_socket;
       
   252 	else
       
   253 		udp = _udp_client_socket;
       
   254 
   290 
   255 	// Put the length in the buffer
   291 	// Put the length in the buffer
   256 	p->buffer[0] = p->size & 0xFF;
   292 	p->buffer[0] = p->size & 0xFF;
   257 	p->buffer[1] = p->size >> 8;
   293 	p->buffer[1] = p->size >> 8;
   258 
   294 
   264 		DEBUG(net, 1)("[NET][UDP] Send error: %i", GET_LAST_ERROR());
   300 		DEBUG(net, 1)("[NET][UDP] Send error: %i", GET_LAST_ERROR());
   265 	}
   301 	}
   266 }
   302 }
   267 
   303 
   268 // Start UDP listener
   304 // Start UDP listener
   269 bool NetworkUDPListen(uint32 host, uint16 port)
   305 bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast)
   270 {
   306 {
   271 	struct sockaddr_in sin;
   307 	struct sockaddr_in sin;
   272 	SOCKET udp;
   308 
   273 
   309 	// Make sure socket is closed
   274 	// Make sure sockets are closed
   310 	closesocket(*udp);
   275 	if (_network_udp_server)
   311 
   276 		closesocket(_udp_server_socket);
   312 	*udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
   277 	else
   313 	if (*udp == INVALID_SOCKET) {
   278 		closesocket(_udp_client_socket);
       
   279 
       
   280 	udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
       
   281 	if (udp == INVALID_SOCKET) {
       
   282 		DEBUG(net, 1)("[NET][UDP] Failed to start UDP support");
   314 		DEBUG(net, 1)("[NET][UDP] Failed to start UDP support");
   283 		return false;
   315 		return false;
   284 	}
   316 	}
   285 
   317 
   286 	// set nonblocking mode for socket
   318 	// set nonblocking mode for socket
   287 	{
   319 	{
   288 		unsigned long blocking = 1;
   320 		unsigned long blocking = 1;
   289 		ioctlsocket(udp, FIONBIO, &blocking);
   321 		ioctlsocket(*udp, FIONBIO, &blocking);
   290 	}
   322 	}
   291 
   323 
   292 	sin.sin_family = AF_INET;
   324 	sin.sin_family = AF_INET;
   293 	// Listen on all IPs
   325 	// Listen on all IPs
   294 	sin.sin_addr.s_addr = host;
   326 	sin.sin_addr.s_addr = host;
   295 	sin.sin_port = htons(port);
   327 	sin.sin_port = htons(port);
   296 
   328 
   297 	if (bind(udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
   329 	if (bind(*udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
   298 		DEBUG(net, 1) ("[NET][UDP] error: bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
   330 		DEBUG(net, 1) ("[NET][UDP] error: bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
   299 		return false;
   331 		return false;
   300 	}
   332 	}
   301 
   333 
   302 	// enable broadcasting
   334 	if (broadcast) {
   303 	// allow reusing
   335 		/* Enable broadcast */
   304 	{
       
   305 		unsigned long val = 1;
   336 		unsigned long val = 1;
   306 		setsockopt(udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
   337 		setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
   307 		val = 1;
   338 	}
   308 		setsockopt(udp, SOL_SOCKET, SO_REUSEADDR, (char *) &val , sizeof(val));
       
   309 	}
       
   310 
       
   311 	if (_network_udp_server)
       
   312 		_udp_server_socket = udp;
       
   313 	else
       
   314 		_udp_client_socket = udp;
       
   315 
   339 
   316 	DEBUG(net, 1)("[NET][UDP] Listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
   340 	DEBUG(net, 1)("[NET][UDP] Listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
   317 
   341 
   318 	return true;
   342 	return true;
   319 }
   343 }
   320 
   344 
   321 // Close UDP connection
   345 // Close UDP connection
   322 void NetworkUDPClose(void)
   346 void NetworkUDPClose(void)
   323 {
   347 {
   324 	DEBUG(net, 1) ("[NET][UDP] Closed listener");
   348 	DEBUG(net, 1) ("[NET][UDP] Closed listeners");
   325 
   349 
   326 	if (_network_udp_server) {
   350 	if (_network_udp_server) {
   327 		closesocket(_udp_server_socket);
   351 		closesocket(_udp_server_socket);
   328 		_udp_server_socket = INVALID_SOCKET;
   352 		_udp_server_socket = INVALID_SOCKET;
       
   353 
       
   354 		closesocket(_udp_master_socket);
       
   355 		_udp_master_socket = INVALID_SOCKET;
       
   356 
   329 		_network_udp_server = false;
   357 		_network_udp_server = false;
   330 		_network_udp_broadcast = 0;
   358 		_network_udp_broadcast = 0;
   331 	} else {
   359 	} else {
   332 		closesocket(_udp_client_socket);
   360 		closesocket(_udp_client_socket);
   333 		_udp_client_socket = INVALID_SOCKET;
   361 		_udp_client_socket = INVALID_SOCKET;
   334 		_network_udp_broadcast = 0;
   362 		_network_udp_broadcast = 0;
   335 	}
   363 	}
   336 }
   364 }
   337 
   365 
   338 // Receive something on UDP level
   366 // Receive something on UDP level
   339 void NetworkUDPReceive(void)
   367 void NetworkUDPReceive(SOCKET udp)
   340 {
   368 {
   341 	struct sockaddr_in client_addr;
   369 	struct sockaddr_in client_addr;
   342 #ifndef __MORPHOS__
   370 #ifndef __MORPHOS__
   343 	int client_len;
   371 	int client_len;
   344 #else
   372 #else
   345 	LONG client_len; // for some reason we need a 'LONG' under MorphOS
   373 	LONG client_len; // for some reason we need a 'LONG' under MorphOS
   346 #endif
   374 #endif
   347 	int nbytes;
   375 	int nbytes;
   348 	static Packet *p = NULL;
   376 	static Packet *p = NULL;
   349 	int packet_len;
   377 	int packet_len;
   350 	SOCKET udp;
       
   351 
       
   352 	if (_network_udp_server)
       
   353 		udp = _udp_server_socket;
       
   354 	else
       
   355 		udp = _udp_client_socket;
       
   356 
   378 
   357 	// If p is NULL, malloc him.. this prevents unneeded mallocs
   379 	// If p is NULL, malloc him.. this prevents unneeded mallocs
   358 	if (p == NULL)
   380 	if (p == NULL)
   359 		p = malloc(sizeof(Packet));
   381 		p = malloc(sizeof(Packet));
   360 
   382 
   381 		p = NULL;
   403 		p = NULL;
   382 	}
   404 	}
   383 }
   405 }
   384 
   406 
   385 // Broadcast to all ips
   407 // Broadcast to all ips
   386 void NetworkUDPBroadCast(void)
   408 void NetworkUDPBroadCast(SOCKET udp)
   387 {
   409 {
   388 	int i;
   410 	int i;
   389 	struct sockaddr_in out_addr;
   411 	struct sockaddr_in out_addr;
   390 	byte *bcptr;
   412 	byte *bcptr;
   391 	uint32 bcaddr;
   413 	uint32 bcaddr;
   406 
   428 
   407 		out_addr.sin_family = AF_INET;
   429 		out_addr.sin_family = AF_INET;
   408 		out_addr.sin_port = htons(_network_server_port);
   430 		out_addr.sin_port = htons(_network_server_port);
   409 		out_addr.sin_addr.s_addr = bcaddr;
   431 		out_addr.sin_addr.s_addr = bcaddr;
   410 
   432 
   411 		NetworkSendUDP_Packet(p, &out_addr);
   433 		NetworkSendUDP_Packet(udp, p, &out_addr);
   412 
   434 
   413 		i++;
   435 		i++;
   414 	}
   436 	}
       
   437 }
       
   438 
       
   439 
       
   440 // Request the the server-list from the master server
       
   441 void NetworkUDPQueryMasterServer(void)
       
   442 {
       
   443 	struct sockaddr_in out_addr;
       
   444 	Packet *p;
       
   445 
       
   446 	if (_udp_client_socket == INVALID_SOCKET)
       
   447 		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
       
   448 			return;
       
   449 
       
   450 	p = NetworkSend_Init(PACKET_UDP_CLIENT_GET_LIST);
       
   451 
       
   452 	out_addr.sin_family = AF_INET;
       
   453 	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
       
   454 	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
       
   455 
       
   456 	// packet only contains protocol version
       
   457 	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
       
   458 
       
   459 	NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
       
   460 
       
   461 	DEBUG(net, 2)("[NET][UDP] Queried Master Server at %s:%d", inet_ntoa(out_addr.sin_addr),ntohs(out_addr.sin_port));
   415 
   462 
   416 	free(p);
   463 	free(p);
   417 }
   464 }
   418 
   465 
   419 // Find all servers
   466 // Find all servers
   423 	if (_network_udp_broadcast > 0)
   470 	if (_network_udp_broadcast > 0)
   424 		return;
   471 		return;
   425 
   472 
   426 	// No UDP-socket yet..
   473 	// No UDP-socket yet..
   427 	if (_udp_client_socket == INVALID_SOCKET)
   474 	if (_udp_client_socket == INVALID_SOCKET)
   428 		if (!NetworkUDPListen(0, 0))
   475 		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
   429 			return;
   476 			return;
   430 
   477 
   431 	DEBUG(net, 0)("[NET][UDP] Searching server");
   478 	DEBUG(net, 0)("[NET][UDP] Searching server");
   432 
   479 
   433 	NetworkUDPBroadCast();
   480 	NetworkUDPBroadCast(_udp_client_socket);
   434 	_network_udp_broadcast = 300; // Stay searching for 300 ticks
   481 	_network_udp_broadcast = 300; // Stay searching for 300 ticks
   435 }
   482 }
   436 
   483 
   437 NetworkGameList *NetworkUDPQueryServer(const byte* host, unsigned short port)
   484 NetworkGameList *NetworkUDPQueryServer(const byte* host, unsigned short port)
   438 {
   485 {
   441 	NetworkGameList *item;
   488 	NetworkGameList *item;
   442 	char hostname[NETWORK_HOSTNAME_LENGTH];
   489 	char hostname[NETWORK_HOSTNAME_LENGTH];
   443 
   490 
   444 	// No UDP-socket yet..
   491 	// No UDP-socket yet..
   445 	if (_udp_client_socket == INVALID_SOCKET)
   492 	if (_udp_client_socket == INVALID_SOCKET)
   446 		if (!NetworkUDPListen(0, 0))
   493 		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
   447 			return NULL;
   494 			return NULL;
   448 
   495 
   449 	ttd_strlcpy(hostname, host, sizeof(hostname));
   496 	ttd_strlcpy(hostname, host, sizeof(hostname));
   450 
   497 
   451 	out_addr.sin_family = AF_INET;
   498 	out_addr.sin_family = AF_INET;
   460 	item->online = false;
   507 	item->online = false;
   461 
   508 
   462 	// Init the packet
   509 	// Init the packet
   463 	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
   510 	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
   464 
   511 
   465 	NetworkSendUDP_Packet(p, &out_addr);
   512 	NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
   466 
   513 
   467 	free(p);
   514 	free(p);
   468 
   515 
   469 	UpdateNetworkGameWindow(false);
   516 	UpdateNetworkGameWindow(false);
   470 	return item;
   517 	return item;
   479 
   526 
   480 	/* Check if we should send an advertise */
   527 	/* Check if we should send an advertise */
   481 	if (!_networking || !_network_server || !_network_udp_server || !_network_advertise)
   528 	if (!_networking || !_network_server || !_network_udp_server || !_network_advertise)
   482 		return;
   529 		return;
   483 
   530 
       
   531 	/* check for socket */
       
   532 	if (_udp_master_socket == INVALID_SOCKET)
       
   533 		if (!NetworkUDPListen(&_udp_master_socket, 0, 0, false))
       
   534 			return;
       
   535 
   484 	/* Only send once in the 450 game-days (about 15 minutes) */
   536 	/* Only send once in the 450 game-days (about 15 minutes) */
   485 	if (_network_last_advertise_date + 450 > _date)
   537 	if (_network_advertise_retries == 0) {
       
   538 		if ( (_network_last_advertise_date + ADVERTISE_NORMAL_INTERVAL) > _date)
       
   539 			return;
       
   540 		_network_advertise_retries = ADVERTISE_RETRY_TIMES;
       
   541 	}
       
   542 
       
   543 	if ( (_network_last_advertise_date + ADVERTISE_RETRY_INTERVAL) > _date)
   486 		return;
   544 		return;
       
   545 
       
   546 	_network_advertise_retries--;
   487 	_network_last_advertise_date = _date;
   547 	_network_last_advertise_date = _date;
   488 
   548 
   489 	/* Find somewhere to send */
   549 	/* Find somewhere to send */
   490 	out_addr.sin_family = AF_INET;
   550 	out_addr.sin_family = AF_INET;
   491 	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
   551 	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
   497 	p = NetworkSend_Init(PACKET_UDP_SERVER_REGISTER);
   557 	p = NetworkSend_Init(PACKET_UDP_SERVER_REGISTER);
   498 	/* Packet is: WELCOME_MESSAGE, Version, server_port */
   558 	/* Packet is: WELCOME_MESSAGE, Version, server_port */
   499 	NetworkSend_string(p, NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
   559 	NetworkSend_string(p, NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
   500 	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
   560 	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
   501 	NetworkSend_uint16(p, _network_server_port);
   561 	NetworkSend_uint16(p, _network_server_port);
   502 	NetworkSendUDP_Packet(p, &out_addr);
   562 	NetworkSendUDP_Packet(_udp_master_socket, p, &out_addr);
       
   563 
   503 	free(p);
   564 	free(p);
   504 }
   565 }
   505 
   566 
   506 void NetworkUDPInitialize(void)
   567 void NetworkUDPInitialize(void)
   507 {
   568 {
   508 	_udp_client_socket = INVALID_SOCKET;
   569 	_udp_client_socket = INVALID_SOCKET;
   509 	_udp_server_socket = INVALID_SOCKET;
   570 	_udp_server_socket = INVALID_SOCKET;
       
   571 	_udp_master_socket = INVALID_SOCKET;
   510 
   572 
   511 	_network_udp_server = false;
   573 	_network_udp_server = false;
   512 	_network_udp_broadcast = 0;
   574 	_network_udp_broadcast = 0;
   513 }
   575 }
   514 
   576