(svn r7821) -Fix: be more strict about the socket from where packets arrive. Do not accept requests about the game server on the master/client socket, do not accept master server acks on the client/server socket, etc.
--- a/src/network/core/udp.c Thu Jan 04 06:57:49 2007 +0000
+++ b/src/network/core/udp.c Thu Jan 04 15:42:09 2007 +0000
@@ -119,7 +119,7 @@
p.next = NULL;
/* Handle the packet */
- NetworkHandleUDPPacket(&p, &client_addr);
+ NetworkHandleUDPPacket(udp, &p, &client_addr);
}
}
--- a/src/network/core/udp.h Thu Jan 04 06:57:49 2007 +0000
+++ b/src/network/core/udp.h Thu Jan 04 15:42:09 2007 +0000
@@ -17,10 +17,11 @@
/**
* Function that is called for every received UDP packet.
+ * @param udp the socket the packet is received on
* @param packet the received packet
* @param client_addr the address of the sender of the packet
*/
-void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr);
+void NetworkHandleUDPPacket(SOCKET udp, Packet *p, struct sockaddr_in *client_addr);
///** Sending/receiving of (large) chuncks of UDP packets **////
--- a/src/network/network_udp.c Thu Jan 04 06:57:49 2007 +0000
+++ b/src/network/network_udp.c Thu Jan 04 15:42:09 2007 +0000
@@ -397,30 +397,31 @@
}
}
-
-// The layout for the receive-functions by UDP
-typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
+/**
+ * Every type of UDP packet should only be received by a single socket;
+ * The socket communicating with the masterserver should receive the
+ * game information of some 'random' host.
+ */
+typedef struct NetworkUDPPacketAndSocket {
+ void (*callback)(Packet *p, struct sockaddr_in *client_addr);
+ SOCKET *incoming_socket;
+} NetworkUPDPacketAndSocket;
-static NetworkUDPPacket* const _network_udp_packet[] = {
- RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
- RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
- RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
- NULL,
- NULL,
- RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER),
- NULL,
- RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST),
- NULL,
- RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS),
- RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS),
+static const NetworkUPDPacketAndSocket _network_udp_packet[PACKET_UDP_END] = {
+ { RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER), &_udp_server_socket },
+ { RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE), &_udp_client_socket },
+ { RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO), &_udp_server_socket },
+ { NULL, NULL },
+ { NULL, NULL },
+ { RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER), &_udp_master_socket },
+ { NULL, NULL },
+ { RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST), &_udp_client_socket },
+ { NULL, NULL },
+ { RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS), &_udp_server_socket },
+ { RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS), &_udp_client_socket },
};
-
-// If this fails, check the array above with network_data.h
-assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
-
-
-void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr)
+void NetworkHandleUDPPacket(SOCKET udp, Packet *p, struct sockaddr_in *client_addr)
{
byte type;
@@ -430,13 +431,15 @@
type = NetworkRecv_uint8(&_udp_cs, p);
- if (type < PACKET_UDP_END && _network_udp_packet[type] != NULL && !_udp_cs.has_quit) {
- _network_udp_packet[type](p, client_addr);
+ if (type < PACKET_UDP_END && *_network_udp_packet[type].incoming_socket == udp && !_udp_cs.has_quit) {
+ _network_udp_packet[type].callback(p, client_addr);
} else {
- if (!_udp_cs.has_quit) {
- DEBUG(net, 0, "[udp] received invalid packet type %d", type);
+ if (*_network_udp_packet[type].incoming_socket != udp) {
+ DEBUG(net, 0, "[udp] received packet on wrong port from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
+ } else if (!_udp_cs.has_quit) {
+ DEBUG(net, 0, "[udp] received invalid packet type %d from %s:%d", type, inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
} else {
- DEBUG(net, 0, "[udp] received illegal packet");
+ DEBUG(net, 0, "[udp] received illegal packet from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
}
}
}