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 { |