00001
00002
00003
00004
00005
00006
00007
00008
00009
00014 #ifdef ENABLE_NETWORK
00015
00016 #include "../../stdafx.h"
00017 #include "../../date_func.h"
00018 #include "../../debug.h"
00019 #include "udp.h"
00020
00025 NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind)
00026 {
00027 if (bind != NULL) {
00028 for (NetworkAddress *addr = bind->Begin(); addr != bind->End(); addr++) {
00029 *this->bind.Append() = *addr;
00030 }
00031 } else {
00032
00033
00034
00035 *this->bind.Append() = NetworkAddress(NULL, 0, AF_INET);
00036 *this->bind.Append() = NetworkAddress(NULL, 0, AF_INET6);
00037 }
00038 }
00039
00040
00045 bool NetworkUDPSocketHandler::Listen()
00046 {
00047
00048 this->Close();
00049
00050 for (NetworkAddress *addr = this->bind.Begin(); addr != this->bind.End(); addr++) {
00051 addr->Listen(SOCK_DGRAM, &this->sockets);
00052 }
00053
00054 return this->sockets.Length() != 0;
00055 }
00056
00060 void NetworkUDPSocketHandler::Close()
00061 {
00062 for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
00063 closesocket(s->second);
00064 }
00065 this->sockets.Clear();
00066 }
00067
00068 NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error)
00069 {
00070 NetworkSocketHandler::CloseConnection(error);
00071 return NETWORK_RECV_STATUS_OKAY;
00072 }
00073
00081 void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast)
00082 {
00083 if (this->sockets.Length() == 0) this->Listen();
00084
00085 for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
00086
00087
00088 NetworkAddress send(*recv);
00089
00090
00091 if (!send.IsFamily(s->first.GetAddress()->ss_family)) continue;
00092
00093 p->PrepareToSend();
00094
00095 #ifndef BEOS_NET_SERVER
00096 if (broadcast) {
00097
00098 unsigned long val = 1;
00099 if (setsockopt(s->second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val)) < 0) {
00100 DEBUG(net, 1, "[udp] setting broadcast failed with: %i", GET_LAST_ERROR());
00101 }
00102 }
00103 #endif
00104
00105
00106 int res = sendto(s->second, (const char*)p->buffer, p->size, 0, (const struct sockaddr *)send.GetAddress(), send.GetAddressLength());
00107 DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString());
00108
00109
00110 if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", send.GetAddressAsString(), GET_LAST_ERROR());
00111
00112 if (!all) break;
00113 }
00114 }
00115
00119 void NetworkUDPSocketHandler::ReceivePackets()
00120 {
00121 for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
00122 for (int i = 0; i < 1000; i++) {
00123 struct sockaddr_storage client_addr;
00124 memset(&client_addr, 0, sizeof(client_addr));
00125
00126 Packet p(this);
00127 socklen_t client_len = sizeof(client_addr);
00128
00129
00130 SetNonBlocking(s->second);
00131 int nbytes = recvfrom(s->second, (char*)p.buffer, SEND_MTU, 0, (struct sockaddr *)&client_addr, &client_len);
00132
00133
00134 if (nbytes <= 0) break;
00135 if (nbytes <= 2) continue;
00136
00137 NetworkAddress address(client_addr, client_len);
00138 p.PrepareToRead();
00139
00140
00141
00142 if (nbytes != p.size) {
00143 DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString());
00144 continue;
00145 }
00146
00147
00148 this->HandleUDPPacket(&p, &address);
00149 }
00150 }
00151 }
00152
00153
00159 void NetworkUDPSocketHandler::SendNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
00160 {
00161 p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 {
00173
00174
00175
00176
00177 const GRFConfig *c;
00178 uint count = 0;
00179
00180
00181 for (c = info->grfconfig; c != NULL; c = c->next) {
00182 if (!HasBit(c->flags, GCF_STATIC)) count++;
00183 }
00184 p->Send_uint8 (count);
00185
00186
00187 for (c = info->grfconfig; c != NULL; c = c->next) {
00188 if (!HasBit(c->flags, GCF_STATIC)) this->SendGRFIdentifier(p, &c->ident);
00189 }
00190 }
00191
00192
00193 p->Send_uint32(info->game_date);
00194 p->Send_uint32(info->start_date);
00195
00196
00197 p->Send_uint8 (info->companies_max);
00198 p->Send_uint8 (info->companies_on);
00199 p->Send_uint8 (info->spectators_max);
00200
00201
00202 p->Send_string(info->server_name);
00203 p->Send_string(info->server_revision);
00204 p->Send_uint8 (info->server_lang);
00205 p->Send_bool (info->use_password);
00206 p->Send_uint8 (info->clients_max);
00207 p->Send_uint8 (info->clients_on);
00208 p->Send_uint8 (info->spectators_on);
00209 p->Send_string(info->map_name);
00210 p->Send_uint16(info->map_width);
00211 p->Send_uint16(info->map_height);
00212 p->Send_uint8 (info->map_set);
00213 p->Send_bool (info->dedicated);
00214 }
00215
00221 void NetworkUDPSocketHandler::ReceiveNetworkGameInfo(Packet *p, NetworkGameInfo *info)
00222 {
00223 static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31);
00224
00225 info->game_info_version = p->Recv_uint8();
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 switch (info->game_info_version) {
00236 case 4: {
00237 GRFConfig **dst = &info->grfconfig;
00238 uint i;
00239 uint num_grfs = p->Recv_uint8();
00240
00241
00242 if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
00243
00244 for (i = 0; i < num_grfs; i++) {
00245 GRFConfig *c = new GRFConfig();
00246 this->ReceiveGRFIdentifier(p, &c->ident);
00247 this->HandleIncomingNetworkGameInfoGRFConfig(c);
00248
00249
00250 *dst = c;
00251 dst = &c->next;
00252 }
00253
00254 }
00255 case 3:
00256 info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
00257 info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
00258
00259 case 2:
00260 info->companies_max = p->Recv_uint8 ();
00261 info->companies_on = p->Recv_uint8 ();
00262 info->spectators_max = p->Recv_uint8 ();
00263
00264 case 1:
00265 p->Recv_string(info->server_name, sizeof(info->server_name));
00266 p->Recv_string(info->server_revision, sizeof(info->server_revision));
00267 info->server_lang = p->Recv_uint8 ();
00268 info->use_password = p->Recv_bool ();
00269 info->clients_max = p->Recv_uint8 ();
00270 info->clients_on = p->Recv_uint8 ();
00271 info->spectators_on = p->Recv_uint8 ();
00272 if (info->game_info_version < 3) {
00273 info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00274 info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00275 }
00276 p->Recv_string(info->map_name, sizeof(info->map_name));
00277 info->map_width = p->Recv_uint16();
00278 info->map_height = p->Recv_uint16();
00279 info->map_set = p->Recv_uint8 ();
00280 info->dedicated = p->Recv_bool ();
00281
00282 if (info->server_lang >= NETWORK_NUM_LANGUAGES) info->server_lang = 0;
00283 if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
00284 }
00285 }
00286
00292 void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, NetworkAddress *client_addr)
00293 {
00294 PacketUDPType type;
00295
00296
00297 this->Reopen();
00298
00299 type = (PacketUDPType)p->Recv_uint8();
00300
00301 switch (this->HasClientQuit() ? PACKET_UDP_END : type) {
00302 case PACKET_UDP_CLIENT_FIND_SERVER: this->Receive_CLIENT_FIND_SERVER(p, client_addr); break;
00303 case PACKET_UDP_SERVER_RESPONSE: this->Receive_SERVER_RESPONSE(p, client_addr); break;
00304 case PACKET_UDP_CLIENT_DETAIL_INFO: this->Receive_CLIENT_DETAIL_INFO(p, client_addr); break;
00305 case PACKET_UDP_SERVER_DETAIL_INFO: this->Receive_SERVER_DETAIL_INFO(p, client_addr); break;
00306 case PACKET_UDP_SERVER_REGISTER: this->Receive_SERVER_REGISTER(p, client_addr); break;
00307 case PACKET_UDP_MASTER_ACK_REGISTER: this->Receive_MASTER_ACK_REGISTER(p, client_addr); break;
00308 case PACKET_UDP_CLIENT_GET_LIST: this->Receive_CLIENT_GET_LIST(p, client_addr); break;
00309 case PACKET_UDP_MASTER_RESPONSE_LIST: this->Receive_MASTER_RESPONSE_LIST(p, client_addr); break;
00310 case PACKET_UDP_SERVER_UNREGISTER: this->Receive_SERVER_UNREGISTER(p, client_addr); break;
00311 case PACKET_UDP_CLIENT_GET_NEWGRFS: this->Receive_CLIENT_GET_NEWGRFS(p, client_addr); break;
00312 case PACKET_UDP_SERVER_NEWGRFS: this->Receive_SERVER_NEWGRFS(p, client_addr); break;
00313 case PACKET_UDP_MASTER_SESSION_KEY: this->Receive_MASTER_SESSION_KEY(p, client_addr); break;
00314
00315 default:
00316 if (this->HasClientQuit()) {
00317 DEBUG(net, 0, "[udp] received invalid packet type %d from %s", type, client_addr->GetAddressAsString());
00318 } else {
00319 DEBUG(net, 0, "[udp] received illegal packet from %s", client_addr->GetAddressAsString());
00320 }
00321 break;
00322 }
00323 }
00324
00330 void NetworkUDPSocketHandler::ReceiveInvalidPacket(PacketUDPType type, NetworkAddress *client_addr)
00331 {
00332 DEBUG(net, 0, "[udp] received packet type %d on wrong port from %s", type, client_addr->GetAddressAsString());
00333 }
00334
00335 void NetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_FIND_SERVER, client_addr); }
00336 void NetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_RESPONSE, client_addr); }
00337 void NetworkUDPSocketHandler::Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_DETAIL_INFO, client_addr); }
00338 void NetworkUDPSocketHandler::Receive_SERVER_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_DETAIL_INFO, client_addr); }
00339 void NetworkUDPSocketHandler::Receive_SERVER_REGISTER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_REGISTER, client_addr); }
00340 void NetworkUDPSocketHandler::Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_MASTER_ACK_REGISTER, client_addr); }
00341 void NetworkUDPSocketHandler::Receive_CLIENT_GET_LIST(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_GET_LIST, client_addr); }
00342 void NetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_MASTER_RESPONSE_LIST, client_addr); }
00343 void NetworkUDPSocketHandler::Receive_SERVER_UNREGISTER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_UNREGISTER, client_addr); }
00344 void NetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_GET_NEWGRFS, client_addr); }
00345 void NetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_NEWGRFS, client_addr); }
00346 void NetworkUDPSocketHandler::Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_MASTER_SESSION_KEY, client_addr); }
00347
00348 #endif