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 if (send(s, (const char*)p.buffer, p.size, 0) < 0) {
00068 DEBUG(net, 0, "send failed with error %d", GET_LAST_ERROR());
00069 }
00070 closesocket(s);
00071 break;
00072 }
00073 }
00074
00075 if (banned) continue;
00076
00077
00078 if (!Tsocket::AllowConnection()) {
00079
00080
00081 Packet p(Tfull_packet);
00082 p.PrepareToSend();
00083
00084 if (send(s, (const char*)p.buffer, p.size, 0) < 0) {
00085 DEBUG(net, 0, "send failed with error %d", GET_LAST_ERROR());
00086 }
00087 closesocket(s);
00088
00089 continue;
00090 }
00091
00092 Tsocket::AcceptConnection(s, address);
00093 }
00094 }
00095
00100 static bool Receive()
00101 {
00102 fd_set read_fd, write_fd;
00103 struct timeval tv;
00104
00105 FD_ZERO(&read_fd);
00106 FD_ZERO(&write_fd);
00107
00108
00109 Tsocket *cs;
00110 FOR_ALL_ITEMS_FROM(Tsocket, idx, cs, 0) {
00111 FD_SET(cs->sock, &read_fd);
00112 FD_SET(cs->sock, &write_fd);
00113 }
00114
00115
00116 for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) {
00117 FD_SET(s->second, &read_fd);
00118 }
00119
00120 tv.tv_sec = tv.tv_usec = 0;
00121 #if !defined(__MORPHOS__) && !defined(__AMIGA__)
00122 if (select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv) < 0) return false;
00123 #else
00124 if (WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL) < 0) return false;
00125 #endif
00126
00127
00128 for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) {
00129 if (FD_ISSET(s->second, &read_fd)) AcceptClient(s->second);
00130 }
00131
00132
00133 FOR_ALL_ITEMS_FROM(Tsocket, idx, cs, 0) {
00134 cs->writable = !!FD_ISSET(cs->sock, &write_fd);
00135 if (FD_ISSET(cs->sock, &read_fd)) {
00136 cs->ReceivePackets();
00137 }
00138 }
00139 return _networking;
00140 }
00141
00147 static bool Listen(uint16 port)
00148 {
00149 assert(sockets.Length() == 0);
00150
00151 NetworkAddressList addresses;
00152 GetBindAddresses(&addresses, port);
00153
00154 for (NetworkAddress *address = addresses.Begin(); address != addresses.End(); address++) {
00155 address->Listen(SOCK_STREAM, &sockets);
00156 }
00157
00158 if (sockets.Length() == 0) {
00159 DEBUG(net, 0, "[server] could not start network: could not create listening socket");
00160 NetworkError(STR_NETWORK_ERROR_SERVER_START);
00161 return false;
00162 }
00163
00164 return true;
00165 }
00166
00168 static void CloseListeners()
00169 {
00170 for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) {
00171 closesocket(s->second);
00172 }
00173 sockets.Clear();
00174 DEBUG(net, 1, "[%s] closed listeners", Tsocket::GetName());
00175 }
00176 };
00177
00178 template <class Tsocket, PacketType Tfull_packet, PacketType Tban_packet> SocketList TCPListenHandler<Tsocket, Tfull_packet, Tban_packet>::sockets;
00179
00180 #endif
00181
00182 #endif