00001
00002
00007 #ifdef ENABLE_NETWORK
00008
00009 #include "../../stdafx.h"
00010 #include "../../debug.h"
00011 #include "../../core/bitmath_func.hpp"
00012 #include "../../core/math_func.hpp"
00013 #include "../../core/alloc_func.hpp"
00014 #include "../../date_func.h"
00015 #include "packet.h"
00016 #include "udp.h"
00017
00025 bool NetworkUDPSocketHandler::Listen(const uint32 host, const uint16 port, const bool broadcast)
00026 {
00027 struct sockaddr_in sin;
00028
00029
00030 this->Close();
00031
00032 this->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
00033 if (!this->IsConnected()) {
00034 DEBUG(net, 0, "[udp] failed to start UDP listener");
00035 return false;
00036 }
00037
00038 SetNonBlocking(this->sock);
00039
00040 sin.sin_family = AF_INET;
00041
00042 sin.sin_addr.s_addr = host;
00043 sin.sin_port = htons(port);
00044
00045 if (bind(this->sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
00046 DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
00047 return false;
00048 }
00049
00050 if (broadcast) {
00051
00052 unsigned long val = 1;
00053 #ifndef BEOS_NET_SERVER
00054 setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
00055 #endif
00056 }
00057
00058 DEBUG(net, 1, "[udp] listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
00059
00060 return true;
00061 }
00062
00066 void NetworkUDPSocketHandler::Close()
00067 {
00068 if (!this->IsConnected()) return;
00069
00070 closesocket(this->sock);
00071 this->sock = INVALID_SOCKET;
00072 }
00073
00074 NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection()
00075 {
00076 this->has_quit = true;
00077 return NETWORK_RECV_STATUS_OKAY;
00078 }
00079
00085 void NetworkUDPSocketHandler::SendPacket(Packet *p, const struct sockaddr_in *recv)
00086 {
00087 int res;
00088
00089 p->PrepareToSend();
00090
00091
00092 res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
00093
00094
00095 if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
00096 }
00097
00101 void NetworkUDPSocketHandler::ReceivePackets()
00102 {
00103 struct sockaddr_in client_addr;
00104 socklen_t client_len;
00105 int nbytes;
00106 Packet p(this);
00107 int packet_len;
00108
00109 if (!this->IsConnected()) return;
00110
00111 packet_len = sizeof(p.buffer);
00112 client_len = sizeof(client_addr);
00113
00114
00115 SetNonBlocking(this->sock);
00116 nbytes = recvfrom(this->sock, (char*)p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
00117
00118
00119 if (nbytes > 2) {
00120 p.PrepareToRead();
00121
00122
00123
00124 if (nbytes != p.size) {
00125 DEBUG(net, 1, "received a packet with mismatching size from %s:%d",
00126 inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
00127
00128 return;
00129 }
00130
00131
00132 this->HandleUDPPacket(&p, &client_addr);
00133 }
00134 }
00135
00136
00142 void NetworkUDPSocketHandler::Send_NetworkGameInfo(Packet *p, const NetworkGameInfo *info)
00143 {
00144 p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 {
00156
00157
00158
00159
00160 const GRFConfig *c;
00161 uint count = 0;
00162
00163
00164 for (c = info->grfconfig; c != NULL; c = c->next) {
00165 if (!HasBit(c->flags, GCF_STATIC)) count++;
00166 }
00167 p->Send_uint8 (count);
00168
00169
00170 for (c = info->grfconfig; c != NULL; c = c->next) {
00171 if (!HasBit(c->flags, GCF_STATIC)) this->Send_GRFIdentifier(p, c);
00172 }
00173 }
00174
00175
00176 p->Send_uint32(info->game_date);
00177 p->Send_uint32(info->start_date);
00178
00179
00180 p->Send_uint8 (info->companies_max);
00181 p->Send_uint8 (info->companies_on);
00182 p->Send_uint8 (info->spectators_max);
00183
00184
00185 p->Send_string(info->server_name);
00186 p->Send_string(info->server_revision);
00187 p->Send_uint8 (info->server_lang);
00188 p->Send_bool (info->use_password);
00189 p->Send_uint8 (info->clients_max);
00190 p->Send_uint8 (info->clients_on);
00191 p->Send_uint8 (info->spectators_on);
00192 p->Send_string(info->map_name);
00193 p->Send_uint16(info->map_width);
00194 p->Send_uint16(info->map_height);
00195 p->Send_uint8 (info->map_set);
00196 p->Send_bool (info->dedicated);
00197 }
00198
00204 void NetworkUDPSocketHandler::Recv_NetworkGameInfo(Packet *p, NetworkGameInfo *info)
00205 {
00206 static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31);
00207
00208 info->game_info_version = p->Recv_uint8();
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 switch (info->game_info_version) {
00219 case 4: {
00220 GRFConfig **dst = &info->grfconfig;
00221 uint i;
00222 uint num_grfs = p->Recv_uint8();
00223
00224
00225 if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
00226
00227 for (i = 0; i < num_grfs; i++) {
00228 GRFConfig *c = CallocT<GRFConfig>(1);
00229 this->Recv_GRFIdentifier(p, c);
00230 this->HandleIncomingNetworkGameInfoGRFConfig(c);
00231
00232
00233 *dst = c;
00234 dst = &c->next;
00235 }
00236 }
00237 case 3:
00238 info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
00239 info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
00240
00241 case 2:
00242 info->companies_max = p->Recv_uint8 ();
00243 info->companies_on = p->Recv_uint8 ();
00244 info->spectators_max = p->Recv_uint8 ();
00245
00246 case 1:
00247 p->Recv_string(info->server_name, sizeof(info->server_name));
00248 p->Recv_string(info->server_revision, sizeof(info->server_revision));
00249 info->server_lang = p->Recv_uint8 ();
00250 info->use_password = p->Recv_bool ();
00251 info->clients_max = p->Recv_uint8 ();
00252 info->clients_on = p->Recv_uint8 ();
00253 info->spectators_on = p->Recv_uint8 ();
00254 if (info->game_info_version < 3) {
00255 info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00256 info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00257 }
00258 p->Recv_string(info->map_name, sizeof(info->map_name));
00259 info->map_width = p->Recv_uint16();
00260 info->map_height = p->Recv_uint16();
00261 info->map_set = p->Recv_uint8 ();
00262 info->dedicated = p->Recv_bool ();
00263
00264 if (info->server_lang >= NETWORK_NUM_LANGUAGES) info->server_lang = 0;
00265 if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
00266 }
00267 }
00268
00273 #define UDP_COMMAND(type) case type: this->NetworkPacketReceive_ ## type ## _command(p, client_addr); break;
00274
00280 void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, const struct sockaddr_in *client_addr)
00281 {
00282 PacketUDPType type;
00283
00284
00285 this->has_quit = false;
00286
00287 type = (PacketUDPType)p->Recv_uint8();
00288
00289 switch (this->HasClientQuit() ? PACKET_UDP_END : type) {
00290 UDP_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER);
00291 UDP_COMMAND(PACKET_UDP_SERVER_RESPONSE);
00292 UDP_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO);
00293 UDP_COMMAND(PACKET_UDP_SERVER_DETAIL_INFO);
00294 UDP_COMMAND(PACKET_UDP_SERVER_REGISTER);
00295 UDP_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER);
00296 UDP_COMMAND(PACKET_UDP_CLIENT_GET_LIST);
00297 UDP_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST);
00298 UDP_COMMAND(PACKET_UDP_SERVER_UNREGISTER);
00299 UDP_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS);
00300 UDP_COMMAND(PACKET_UDP_SERVER_NEWGRFS);
00301
00302 default:
00303 if (this->HasClientQuit()) {
00304 DEBUG(net, 0, "[udp] received invalid packet type %d from %s:%d", type, inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));
00305 } else {
00306 DEBUG(net, 0, "[udp] received illegal packet from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));
00307 }
00308 break;
00309 }
00310 }
00311
00318 #define DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(type) \
00319 void NetworkUDPSocketHandler::NetworkPacketReceive_## type ##_command(\
00320 Packet *p, const struct sockaddr_in *client_addr) { \
00321 DEBUG(net, 0, "[udp] received packet type %d on wrong port from %s:%d", \
00322 type, inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); \
00323 }
00324
00325 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER);
00326 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE);
00327 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO);
00328 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_DETAIL_INFO);
00329 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_REGISTER);
00330 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER);
00331 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_LIST);
00332 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST);
00333 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_UNREGISTER);
00334 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS);
00335 DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS);
00336
00337 #endif