src/network/network_udp.c
branchcustombridgeheads
changeset 5648 1608018c5ff2
parent 5643 3778051e8095
equal deleted inserted replaced
5647:cbde85c8c878 5648:1608018c5ff2
    26 	ADVERTISE_NORMAL_INTERVAL = 30000, // interval between advertising in ticks (15 minutes)
    26 	ADVERTISE_NORMAL_INTERVAL = 30000, // interval between advertising in ticks (15 minutes)
    27 	ADVERTISE_RETRY_INTERVAL  =   300, // readvertise when no response after this many ticks (9 seconds)
    27 	ADVERTISE_RETRY_INTERVAL  =   300, // readvertise when no response after this many ticks (9 seconds)
    28 	ADVERTISE_RETRY_TIMES     =     3  // give up readvertising after this much failed retries
    28 	ADVERTISE_RETRY_TIMES     =     3  // give up readvertising after this much failed retries
    29 };
    29 };
    30 
    30 
    31 #define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
    31 #define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, const struct sockaddr_in *client_addr)
    32 
    32 
    33 static NetworkClientState _udp_cs;
    33 static NetworkClientState _udp_cs;
    34 
    34 
    35 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
    35 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
    36 {
    36 {
    48 	_network_game_info.map_set       = _opt.landscape;
    48 	_network_game_info.map_set       = _opt.landscape;
    49 	_network_game_info.companies_on  = ActivePlayerCount();
    49 	_network_game_info.companies_on  = ActivePlayerCount();
    50 	_network_game_info.spectators_on = NetworkSpectatorCount();
    50 	_network_game_info.spectators_on = NetworkSpectatorCount();
    51 	_network_game_info.grfconfig     = _grfconfig;
    51 	_network_game_info.grfconfig     = _grfconfig;
    52 
    52 
    53 	NetworkSend_NetworkGameInfo(p, &_network_game_info);
    53 	NetworkSend_NetworkGameInfo(packet, &_network_game_info);
    54 
    54 
    55 	// Let the client know that we are here
    55 	// Let the client know that we are here
    56 	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
    56 	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
    57 
    57 
    58 	free(packet);
    58 	free(packet);
   395 			ttd_strlcpy(unknown_name, name, NETWORK_GRF_NAME_LENGTH);
   395 			ttd_strlcpy(unknown_name, name, NETWORK_GRF_NAME_LENGTH);
   396 		}
   396 		}
   397 	}
   397 	}
   398 }
   398 }
   399 
   399 
   400 
   400 /**
   401 // The layout for the receive-functions by UDP
   401  * Every type of UDP packet should only be received by a single socket;
   402 typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
   402  * The socket communicating with the masterserver should receive the
   403 
   403  * game information of some 'random' host.
   404 static NetworkUDPPacket* const _network_udp_packet[] = {
   404  */
   405 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
   405 typedef struct NetworkUDPPacketAndSocket {
   406 	RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
   406 	void (*callback)(Packet *p, const struct sockaddr_in *client_addr);
   407 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
   407 	SOCKET *incoming_socket;
   408 	NULL,
   408 } NetworkUPDPacketAndSocket;
   409 	NULL,
   409 
   410 	RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER),
   410 static const NetworkUPDPacketAndSocket _network_udp_packet[PACKET_UDP_END] = {
   411 	NULL,
   411 	{ RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),   &_udp_server_socket },
   412 	RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST),
   412 	{ RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),      &_udp_client_socket },
   413 	NULL,
   413 	{ RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),   &_udp_server_socket },
   414 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS),
   414 	{ NULL,                                             NULL                },
   415 	RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS),
   415 	{ NULL,                                             NULL                },
       
   416 	{ RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER),  &_udp_master_socket },
       
   417 	{ NULL,                                             NULL                },
       
   418 	{ RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST), &_udp_client_socket },
       
   419 	{ NULL,                                             NULL                },
       
   420 	{ RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS),   &_udp_server_socket },
       
   421 	{ RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS),       &_udp_client_socket },
   416 };
   422 };
   417 
   423 
   418 
   424 void NetworkHandleUDPPacket(const SOCKET udp, Packet *p, const struct sockaddr_in *client_addr)
   419 // If this fails, check the array above with network_data.h
       
   420 assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
       
   421 
       
   422 
       
   423 void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr)
       
   424 {
   425 {
   425 	byte type;
   426 	byte type;
   426 
   427 
   427 	/* Fake a client, so we can see when there is an illegal packet */
   428 	/* Fake a client, so we can see when there is an illegal packet */
   428 	_udp_cs.socket = INVALID_SOCKET;
   429 	_udp_cs.socket = INVALID_SOCKET;
   429 	_udp_cs.has_quit = false;
   430 	_udp_cs.has_quit = false;
   430 
   431 
   431 	type = NetworkRecv_uint8(&_udp_cs, p);
   432 	type = NetworkRecv_uint8(&_udp_cs, p);
   432 
   433 
   433 	if (type < PACKET_UDP_END && _network_udp_packet[type] != NULL && !_udp_cs.has_quit) {
   434 	if (type < PACKET_UDP_END && *_network_udp_packet[type].incoming_socket == udp && !_udp_cs.has_quit) {
   434 		_network_udp_packet[type](p, client_addr);
   435 		_network_udp_packet[type].callback(p, client_addr);
   435 	} else {
   436 	} else {
   436 		if (!_udp_cs.has_quit) {
   437 		if (*_network_udp_packet[type].incoming_socket != udp) {
   437 			DEBUG(net, 0, "[udp] received invalid packet type %d", type);
   438 			DEBUG(net, 0, "[udp] received packet on wrong port from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
       
   439 		} else if (!_udp_cs.has_quit) {
       
   440 			DEBUG(net, 0, "[udp] received invalid packet type %d from %s:%d", type,  inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
   438 		} else {
   441 		} else {
   439 			DEBUG(net, 0, "[udp] received illegal packet");
   442 			DEBUG(net, 0, "[udp] received illegal packet from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
   440 		}
   443 		}
   441 	}
   444 	}
   442 }
   445 }
   443 
   446 
   444 
   447 
   445 // Close UDP connection
   448 // Close UDP connection
   446 void NetworkUDPClose(void)
   449 void NetworkUDPStop(void)
   447 {
   450 {
   448 	DEBUG(net, 1, "[udp] closed listeners");
   451 	DEBUG(net, 1, "[udp] closed listeners");
   449 
   452 
   450 	if (_network_udp_server) {
   453 	if (_network_udp_server) {
   451 		if (_udp_server_socket != INVALID_SOCKET) {
   454 		NetworkUDPClose(&_udp_server_socket);
   452 			closesocket(_udp_server_socket);
   455 		NetworkUDPClose(&_udp_master_socket);
   453 			_udp_server_socket = INVALID_SOCKET;
       
   454 		}
       
   455 
       
   456 		if (_udp_master_socket != INVALID_SOCKET) {
       
   457 			closesocket(_udp_master_socket);
       
   458 			_udp_master_socket = INVALID_SOCKET;
       
   459 		}
       
   460 
       
   461 		_network_udp_server = false;
       
   462 		_network_udp_broadcast = 0;
       
   463 	} else {
   456 	} else {
   464 		if (_udp_client_socket != INVALID_SOCKET) {
   457 		NetworkUDPClose(&_udp_client_socket);
   465 			closesocket(_udp_client_socket);
   458 	}
   466 			_udp_client_socket = INVALID_SOCKET;
   459 
   467 		}
   460 	_network_udp_server = false;
   468 		_network_udp_broadcast = 0;
   461 	_network_udp_broadcast = 0;
   469 	}
       
   470 }
   462 }
   471 
   463 
   472 // Broadcast to all ips
   464 // Broadcast to all ips
   473 static void NetworkUDPBroadCast(SOCKET udp)
   465 static void NetworkUDPBroadCast(SOCKET udp)
   474 {
   466 {