![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 /* 00002 Copyright (c) 2009 Christopher A. Taylor. All rights reserved. 00003 00004 Redistribution and use in source and binary forms, with or without 00005 modification, are permitted provided that the following conditions are met: 00006 00007 * Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, 00010 this list of conditions and the following disclaimer in the documentation 00011 and/or other materials provided with the distribution. 00012 * Neither the name of LibCat nor the names of its contributors may be used 00013 to endorse or promote products derived from this software without 00014 specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00019 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00020 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00021 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00022 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00023 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00024 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00025 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00026 POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00029 #ifndef CAT_THREAD_POOL_UDP_ENDPOINT_HPP 00030 #define CAT_THREAD_POOL_UDP_ENDPOINT_HPP 00031 00032 /* 00033 Windows version of thread pool sockets with IO Completion Ports 00034 00035 Included from <cat/net/ThreadPoolSockets.hpp> 00036 Do not include directly 00037 */ 00038 00039 #include <MSWSock.h> 00040 #include <cat/port/WindowsInclude.hpp> 00041 00042 namespace cat { 00043 00044 00046 00047 // AcceptEx() OVERLAPPED structure 00048 struct AcceptExOverlapped 00049 { 00050 TypedOverlapped tov; 00051 Socket acceptSocket; 00052 00053 // Space pre-allocated to receive addresses 00054 // NOTE: This is not necessarily how the addresses are organized in memory 00055 struct 00056 { 00057 // Not necessarily an IPv6 address either! 00058 sockaddr_in6 addr[2]; 00059 u8 padding[2*16]; 00060 } addresses; 00061 00062 void Set(Socket s); 00063 }; 00064 00065 // WSARecvFrom() OVERLAPPED structure 00066 struct RecvFromOverlapped 00067 { 00068 TypedOverlapped tov; 00069 00070 // Not necessarily and IPv6 address, 00071 // but we allocate enough space for one 00072 int addrLen; 00073 sockaddr_in6 addr; 00074 00075 // data follows... 00076 00077 void Reset(); 00078 }; 00079 00080 00081 /* 00082 class TCPServer 00083 00084 Object that represents a TCP server bound to a single port 00085 00086 Overload InstantiateServerConnection() to subclass connections with the server 00087 */ 00088 class TCPServer : public ThreadRefObject 00089 { 00090 friend class TCPConnection; 00091 friend class ThreadPool; 00092 00093 public: 00094 TCPServer(); 00095 virtual ~TCPServer(); 00096 00097 bool ValidServer(); 00098 Port GetPort(); 00099 00100 bool Bind(Port port = 0); 00101 void Close(); 00102 00103 protected: 00104 virtual TCPConnection *InstantiateServerConnection() = 0; 00105 00106 private: 00107 Socket _socket; 00108 LPFN_ACCEPTEX _lpfnAcceptEx; 00109 LPFN_GETACCEPTEXSOCKADDRS _lpfnGetAcceptExSockAddrs; 00110 LPFN_DISCONNECTEX _lpfnDisconnectEx; 00111 Port _port; 00112 00113 private: 00114 bool QueueAcceptEx(); 00115 bool QueueAccepts(); 00116 00117 void OnAcceptExComplete(int error, AcceptExOverlapped *overlapped); 00118 }; 00119 00120 00121 /* 00122 class TCPConnection 00123 00124 Object that represents a TCPServer's connection from a TCPClient 00125 00126 Object is instantiated just before accepting a connection 00127 00128 DisconnectClient() : Disconnect the client 00129 PostToClient() : Send a message to the client 00130 ValidServerConnection() : Returns true iff the connection is valid 00131 00132 OnConnectFromClient() : Return false to deny this connection 00133 OnReadFromClient() : Return false to disconnect the client in response to a message 00134 OnWriteToClient() : Informs the derived class that data has been sent 00135 OnDisconectFromClient() : Informs the derived class that the client has disconnected 00136 */ 00137 class TCPConnection : public ThreadRefObject 00138 { 00139 friend class TCPServer; 00140 friend class ThreadPool; 00141 00142 public: 00143 TCPConnection(); 00144 virtual ~TCPConnection(); 00145 00146 bool ValidServerConnection(); 00147 00148 void DisconnectClient(); 00149 bool PostToClient(void *buffer, u32 bytes); 00150 00151 protected: 00152 virtual bool OnConnectFromClient(const NetAddr &remoteClientAddress) = 0; // false = disconnect 00153 virtual bool OnReadFromClient(u8 *data, u32 bytes) = 0; // false = disconnect 00154 virtual void OnWriteToClient(u32 bytes) = 0; 00155 virtual void OnDisconnectFromClient() = 0; 00156 00157 private: 00158 Socket _socket; 00159 LPFN_DISCONNECTEX _lpfnDisconnectEx; 00160 TypedOverlapped *_recvOv; 00161 volatile u32 _disconnecting; 00162 00163 private: 00164 bool AcceptConnection(Socket listenSocket, Socket acceptSocket, 00165 LPFN_DISCONNECTEX lpfnDisconnectEx, const NetAddr &acceptAddress, 00166 const NetAddr &remoteClientAddress); 00167 00168 bool QueueWSARecv(); 00169 void OnWSARecvComplete(int error, u32 bytes); 00170 00171 bool QueueWSASend(TypedOverlapped *sendOv, u32 bytes); 00172 void OnWSASendComplete(int error, u32 bytes); 00173 00174 bool QueueDisconnectEx(); 00175 void OnDisconnectExComplete(int error); 00176 }; 00177 00178 00179 /* 00180 class TCPClient 00181 00182 Object that represents a TCPClient bound to a single port 00183 00184 ValidClient() : Returns true iff the client socket is valid 00185 00186 Connect() : Connects to the given address 00187 DisconnectServer() : Disconnects from the server 00188 PostToServer() : Send a message to the server (will fail if not connected) 00189 00190 OnConnectToServer() : Called when connection is accepted 00191 OnReadFromServer() : Return false to disconnect the server in response to data 00192 OnWriteToServer() : Informs the derived class that data has been sent 00193 OnDisconnectFromServer() : Informs the derived class that the server has disconnected 00194 */ 00195 class TCPClient : public ThreadRefObject 00196 { 00197 friend class ThreadPool; 00198 00199 public: 00200 TCPClient(); 00201 virtual ~TCPClient(); 00202 00203 bool ValidClient(); 00204 00205 bool Connect(const NetAddr &remoteServerAddress); 00206 void DisconnectServer(); 00207 bool PostToServer(void *buffer, u32 bytes); 00208 00209 protected: 00210 virtual void OnConnectToServer() = 0; 00211 virtual bool OnReadFromServer(u8 *data, u32 bytes) = 0; // false = disconnect 00212 virtual void OnWriteToServer(u32 bytes) = 0; 00213 virtual void OnDisconnectFromServer() = 0; 00214 00215 private: 00216 Socket _socket; 00217 TypedOverlapped *_recvOv; 00218 volatile u32 _disconnecting; 00219 bool _ipv6; 00220 00221 private: 00222 bool QueueConnectEx(const NetAddr &remoteServerAddress); 00223 void OnConnectExComplete(int error); 00224 00225 bool QueueWSARecv(); 00226 void OnWSARecvComplete(int error, u32 bytes); 00227 00228 bool QueueWSASend(TypedOverlapped *sendOv, u32 bytes); 00229 void OnWSASendComplete(int error, u32 bytes); 00230 00231 bool QueueDisconnectEx(); 00232 void OnDisconnectExComplete(int error); 00233 }; 00234 00235 00236 /* 00237 class TCPClientQueued 00238 00239 Base class for a TCP client that needs to queue up data for sending before 00240 a connection has been established. e.g. Uplink for a proxy server. 00241 00242 PostQueuedToServer() : Call in OnConnectToServer() to post the queued messages. 00243 */ 00244 class TCPClientQueued : public TCPClient 00245 { 00246 private: 00247 volatile bool _queuing; 00248 00249 Mutex _queueLock; 00250 void *_queueBuffer; 00251 u32 _queueBytes; 00252 00253 protected: 00254 void PostQueuedToServer(); 00255 00256 public: 00257 TCPClientQueued(); 00258 virtual ~TCPClientQueued(); 00259 00260 bool PostToServer(void *buffer, u32 bytes); 00261 }; 00262 00263 00264 /* 00265 class UDPEndpoint 00266 00267 Object that represents a UDP endpoint bound to a single port 00268 */ 00269 class UDPEndpoint : public ThreadRefObject 00270 { 00271 friend class ThreadPool; 00272 00273 public: 00274 UDPEndpoint(); 00275 virtual ~UDPEndpoint(); 00276 00277 bool Valid(); 00278 Port GetPort(); 00279 00280 // Is6() result is only valid AFTER Bind() 00281 CAT_INLINE bool Is6() { return _ipv6; } 00282 00283 // For servers: Bind() with ignoreUnreachable = true ((default)) 00284 // For clients: Bind() with ignoreUnreachable = false and call this 00285 // after the first packet from the server is received. 00286 bool IgnoreUnreachable(); 00287 00288 void Close(); // Invalidates this object 00289 bool Bind(Port port = 0, bool ignoreUnreachable = true); 00290 bool QueueWSARecvFrom(); 00291 00292 // If Is6() == true, the address must be promoted to IPv6 00293 // before calling Post() with addr.PromoteTo6() 00294 bool Post(const NetAddr &addr, void *data, u32 bytes); 00295 00296 protected: 00297 virtual void OnRead(ThreadPoolLocalStorage *tls, const NetAddr &addr, u8 *data, u32 bytes) = 0; // false = close 00298 virtual void OnWrite(u32 bytes) = 0; 00299 virtual void OnClose() = 0; 00300 virtual void OnUnreachable(const NetAddr &addr) {} // Only IP is valid 00301 00302 private: 00303 Socket _socket; 00304 Port _port; 00305 volatile u32 _closing; 00306 bool _ipv6; 00307 00308 private: 00309 bool QueueWSARecvFrom(RecvFromOverlapped *recvOv); 00310 void OnWSARecvFromComplete(ThreadPoolLocalStorage *tls, int error, RecvFromOverlapped *recvOv, u32 bytes); 00311 00312 bool QueueWSASendTo(const NetAddr &addr, TypedOverlapped *sendOv, u32 bytes); 00313 void OnWSASendToComplete(int error, u32 bytes); 00314 }; 00315 00316 00317 } // namespace cat 00318 00319 #endif // CAT_THREAD_POOL_UDP_ENDPOINT_HPP
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.