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 "udp.h"
00019
00024 NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind)
00025 {
00026 if (bind != NULL) {
00027 for (NetworkAddress *addr = bind->Begin(); addr != bind->End(); addr++) {
00028 *this->bind.Append() = *addr;
00029 }
00030 } else {
00031
00032
00033
00034 *this->bind.Append() = NetworkAddress(NULL, 0, AF_INET);
00035 *this->bind.Append() = NetworkAddress(NULL, 0, AF_INET6);
00036 }
00037 }
00038
00039
00044 bool NetworkUDPSocketHandler::Listen()
00045 {
00046
00047 this->Close();
00048
00049 for (NetworkAddress *addr = this->bind.Begin(); addr != this->bind.End(); addr++) {
00050 addr->Listen(SOCK_DGRAM, &this->sockets);
00051 }
00052
00053 return this->sockets.Length() != 0;
00054 }
00055
00059 void NetworkUDPSocketHandler::Close()
00060 {
00061 for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
00062 closesocket(s->second);
00063 }
00064 this->sockets.Clear();
00065 }
00066
00067 NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error)
00068 {
00069 NetworkSocketHandler::CloseConnection(error);
00070 return NETWORK_RECV_STATUS_OKAY;
00071 }
00072
00080 void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast)
00081 {
00082 if (this->sockets.Length() == 0) this->Listen();
00083
00084 for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
00085
00086
00087 NetworkAddress send(*recv);
00088
00089
00090 if (!send.IsFamily(s->first.GetAddress()->ss_family)) continue;
00091
00092 p->PrepareToSend();
00093
00094 #ifndef BEOS_NET_SERVER
00095 if (broadcast) {
00096
00097 unsigned long val = 1;
00098 setsockopt(s->second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val));
00099 }
00100 #endif
00101
00102
00103 int res = sendto(s->second, (const char*)p->buffer, p->size, 0, (struct sockaddr *)send.GetAddress(), send.GetAddressLength());
00104 DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString());
00105
00106
00107 if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", send.GetAddressAsString(), GET_LAST_ERROR());
00108
00109 if (!all) break;
00110 }
00111 }
00112
00116 void NetworkUDPSocketHandler::ReceivePackets()
00117 {
00118 for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
00119 struct sockaddr_storage client_addr;
00120 memset(&client_addr, 0, sizeof(client_addr));
00121
00122 Packet p(this);
00123 int packet_len = sizeof(p.buffer);
00124 socklen_t client_len = sizeof(client_addr);
00125
00126
00127 SetNonBlocking(s->second);
00128 int nbytes = recvfrom(s->second, (char*)p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
00129
00130
00131 if (nbytes > 2) {
00132 NetworkAddress address(client_addr, client_len);
00133 p.PrepareToRead();
00134
00135
00136
00137 if (nbytes != p.size) {
00138 DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString());
00139 return;
00140 }
00141
00142
00143 this->HandleUDPPacket(&p, &address);
00144 }
00145 }
00146 }
00147
00148
00154 void NetworkUDPSocketHandler::Send_NetworkGameInfo(Packet *p, const NetworkGameInfo *info)
00155 {
00156 p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 {
00168
00169
00170
00171
00172 const GRFConfig *c;
00173 uint count = 0;
00174
00175
00176 for (c = info->grfconfig; c != NULL; c = c->next) {
00177 if (!HasBit(c->flags, GCF_STATIC)) count++;
00178 }
00179 p->Send_uint8 (count);
00180
00181
00182 for (c = info->grfconfig; c != NULL; c = c->next) {
00183 if (!HasBit(c->flags, GCF_STATIC)) this->Send_GRFIdentifier(p, c);
00184 }
00185 }
00186
00187
00188 p->Send_uint32(info->game_date);
00189 p->Send_uint32(info->start_date);
00190
00191
00192 p->Send_uint8 (info->companies_max);
00193 p->Send_uint8 (info->companies_on);
00194 p->Send_uint8 (info->spectators_max);
00195
00196
00197 p->Send_string(info->server_name);
00198 p->Send_string(info->server_revision);
00199 p->Send_uint8 (info->server_lang);
00200 p->Send_bool (info->use_password);
00201 p->Send_uint8 (info->clients_max);
00202 p->Send_uint8 (info->clients_on);
00203 p->Send_uint8 (info->spectators_on);
00204 p->Send_string(info->map_name);
00205 p->Send_uint16(info->map_width);
00206 p->Send_uint16(info->map_height);
00207 p->Send_uint8 (info->map_set);
00208 p->Send_bool (info->dedicated);
00209 }
00210
00216 void NetworkUDPSocketHandler::Recv_NetworkGameInfo(Packet *p, NetworkGameInfo *info)
00217 {
00218 static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31);
00219
00220 info->game_info_version = p->Recv_uint8();
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 switch (info->game_info_version) {
00231 case 4: {
00232 GRFConfig **dst = &info->grfconfig;
00233 uint i;
00234 uint num_grfs = p->Recv_uint8();
00235
00236
00237 if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
00238
00239 for (i = 0; i < num_grfs; i++) {
00240 GRFConfig *c = CallocT<GRFConfig>(1);
00241 this->Recv_GRFIdentifier(p, c);
00242 this->HandleIncomingNetworkGameInfoGRFConfig(c);
00243
00244
00245 *dst = c;
00246 dst = &c->next;
00247 }
00248 }
00249 case 3:
00250 info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
00251 info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
00252
00253 case 2:
00254 info->companies_max = p->Recv_uint8 ();
00255 info->companies_on = p->Recv_uint8 ();
00256 info->spectators_max = p->Recv_uint8 ();
00257
00258 case 1:
00259 p->Recv_string(info->server_name, sizeof(info->server_name));
00260 p->Recv_string(info->server_revision, sizeof(info->server_revision));
00261 info->server_lang = p->Recv_uint8 ();
00262 info->use_password = p->Recv_bool ();
00263 info->clients_max = p->Recv_uint8 ();
00264 info->clients_on = p->Recv_uint8 ();
00265 info->spectators_on = p->Recv_uint8 ();
00266 if (info->game_info_version < 3) {
00267 info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00268 info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00269 }
00270 p->Recv_string(info->map_name, sizeof(info->map_name));
00271 info->map_width = p->Recv_uint16();
00272 info->map_height = p->Recv_uint16();
00273 info->map_set = p->Recv_uint8 ();
00274 info->dedicated = p->Recv_bool ();
00275
00276 if (info->server_lang >= NETWORK_NUM_LANGUAGES) info->server_lang = 0;
00277 if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
00278 }
00279 }
00280
00285 #define UDP_COMMAND(type) case type: this->NetworkPacketReceive_ ## type ## _command(p, client_addr); break;
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 UDP_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER);
00303 UDP_COMMAND(PACKET_UDP_SERVER_RESPONSE);
00304 UDP_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO);
00305 UDP_COMMAND(PACKET_UDP_SERVER_DETAIL_INFO);
00306 UDP_COMMAND(PACKET_UDP_SERVER_REGISTER);
00307 UDP_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER);
00308 UDP_COMMAND(PACKET_UDP_CLIENT_GET_LIST);
00309 UDP_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST);
00310 UDP_COMMAND(PACKET_UDP_SERVER_UNREGISTER);
00311 UDP_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS);
00312 UDP_COMMAND(PACKET_UDP_SERVER_NEWGRFS);
00313 UDP_COMMAND(PACKET_UDP_MASTER_SESSION_KEY);
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
00331 #define DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(type) \
00332 void NetworkUDPSocketHandler::NetworkPacketReceive_## type ##_command(\
00333 Packet *p, NetworkAddress *client_addr) { \
00334 DEBUG(net, 0, "[udp] received packet type %d on wrong port from %s", \
00335 type, client_addr->GetAddressAsString()); \
00336 }
00337
00338 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER);
00339 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE);
00340 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO);
00341 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_DETAIL_INFO);
00342 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_REGISTER);
00343 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER);
00344 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_LIST);
00345 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST);
00346 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_UNREGISTER);
00347 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS);
00348 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS);
00349 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_SESSION_KEY);
00350
00351 #endif