00001
00002
00003
00004
00005
00006
00007
00008
00009
00014 #ifndef NETWORK_CORE_TCP_LISTEN_H
00015 #define NETWORK_CORE_TCP_LISTEN_H
00016
00017 #include "tcp.h"
00018 #include "../network.h"
00019 #include "../../core/pool_type.hpp"
00020 #include "../../debug.h"
00021 #include "table/strings.h"
00022
00023 #ifdef ENABLE_NETWORK
00024
00031 template <class Tsocket, PacketType Tfull_packet, PacketType Tban_packet>
00032 class TCPListenHandler {
00034 static SocketList sockets;
00035
00036 public:
00041 static void AcceptClient(SOCKET ls)
00042 {
00043 for (;;) {
00044 struct sockaddr_storage sin;
00045 memset(&sin, 0, sizeof(sin));
00046 socklen_t sin_len = sizeof(sin);
00047 SOCKET s = accept(ls, (struct sockaddr*)&sin, &sin_len);
00048 if (s == INVALID_SOCKET) return;
00049
00050 SetNonBlocking(s);
00051
00052 NetworkAddress address(sin, sin_len);
00053 DEBUG(net, 1, "[%s] Client connected from %s on frame %d", Tsocket::GetName(), address.GetHostname(), _frame_counter);
00054
00055 SetNoDelay(s);
00056
00057
00058 bool banned = false;
00059 for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++) {
00060 banned = address.IsInNetmask(*iter);
00061 if (banned) {
00062 Packet p(Tban_packet);
00063 p.PrepareToSend();
00064
00065 DEBUG(net, 1, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), *iter);
00066
00067 send(s, (const char*)p.buffer, p.size, 0);
00068 closesocket(s);
00069 break;
00070 }
00071 }
00072
00073 if (banned) continue;
00074
00075
00076 if (!Tsocket::AllowConnection()) {
00077
00078
00079 Packet p(Tfull_packet);
00080 p.PrepareToSend();
00081
00082 send(s, (const char*)p.buffer, p.size, 0);
00083 closesocket(s);
00084
00085 continue;
00086 }
00087
00088 Tsocket::AcceptConnection(s, address);
00089 }
00090 }
00091
00096 static bool Receive()
00097 {
00098 fd_set read_fd, write_fd;
00099 struct timeval tv;
00100
00101 FD_ZERO(&read_fd);
00102 FD_ZERO(&write_fd);
00103
00104
00105 Tsocket *cs;
00106 FOR_ALL_ITEMS_FROM(Tsocket, idx, cs, 0) {
00107 FD_SET(cs->sock, &read_fd);
00108 FD_SET(cs->sock, &write_fd);
00109 }
00110
00111
00112 for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) {
00113 FD_SET(s->second, &read_fd);
00114 }
00115
00116 tv.tv_sec = tv.tv_usec = 0;
00117 #if !defined(__MORPHOS__) && !defined(__AMIGA__)
00118 select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
00119 #else
00120 WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
00121 #endif
00122
00123
00124 for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) {
00125 if (FD_ISSET(s->second, &read_fd)) AcceptClient(s->second);
00126 }
00127
00128
00129 FOR_ALL_ITEMS_FROM(Tsocket, idx, cs, 0) {
00130 cs->writable = !!FD_ISSET(cs->sock, &write_fd);
00131 if (FD_ISSET(cs->sock, &read_fd)) {
00132 cs->ReceivePackets();
00133 }
00134 }
00135 return _networking;
00136 }
00137
00143 static bool Listen(uint16 port)
00144 {
00145 assert(sockets.Length() == 0);
00146
00147 NetworkAddressList addresses;
00148 GetBindAddresses(&addresses, port);
00149
00150 for (NetworkAddress *address = addresses.Begin(); address != addresses.End(); address++) {
00151 address->Listen(SOCK_STREAM, &sockets);
00152 }
00153
00154 if (sockets.Length() == 0) {
00155 DEBUG(net, 0, "[server] could not start network: could not create listening socket");
00156 NetworkError(STR_NETWORK_ERROR_SERVER_START);
00157 return false;
00158 }
00159
00160 return true;
00161 }
00162
00164 static void CloseListeners()
00165 {
00166 for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) {
00167 closesocket(s->second);
00168 }
00169 sockets.Clear();
00170 DEBUG(net, 1, "[%s] closed listeners", Tsocket::GetName());
00171 }
00172 };
00173
00174 template <class Tsocket, PacketType Tfull_packet, PacketType Tban_packet> SocketList TCPListenHandler<Tsocket, Tfull_packet, Tban_packet>::sockets;
00175
00176 #endif
00177
00178 #endif