![]() |
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_SOCKETS_HPP 00030 #define CAT_THREAD_POOL_SOCKETS_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 /* 00045 class TCPConnection 00046 00047 Object that represents a TCPServer's connection from a TCPClient 00048 00049 Object is instantiated just before accepting a connection 00050 00051 DisconnectClient() : Disconnect the client 00052 PostToClient() : Send a message to the client 00053 ValidServerConnection() : Returns true iff the connection is valid 00054 00055 OnConnectFromClient() : Return false to deny this connection 00056 OnReadFromClient() : Return false to disconnect the client in response to a message 00057 OnWriteToClient() : Informs the derived class that data has been sent 00058 OnDisconectFromClient() : Informs the derived class that the client has disconnected 00059 */ 00060 class TCPConnection : public ThreadRefObject 00061 { 00062 friend class TCPServer; 00063 friend class ThreadPool; 00064 00065 public: 00066 TCPConnection(); 00067 virtual ~TCPConnection(); 00068 00069 bool ValidServerConnection(); 00070 00071 void DisconnectClient(); 00072 bool PostToClient(void *buffer, u32 bytes); 00073 00074 protected: 00075 virtual bool OnConnectFromClient(const NetAddr &remoteClientAddress) = 0; // false = disconnect 00076 virtual bool OnReadFromClient(u8 *data, u32 bytes) = 0; // false = disconnect 00077 virtual void OnWriteToClient(u32 bytes) = 0; 00078 virtual void OnDisconnectFromClient() = 0; 00079 00080 private: 00081 Socket _socket; 00082 LPFN_DISCONNECTEX _lpfnDisconnectEx; 00083 TypedOverlapped *_recvOv; 00084 volatile u32 _disconnecting; 00085 00086 private: 00087 bool AcceptConnection(Socket listenSocket, Socket acceptSocket, 00088 LPFN_DISCONNECTEX lpfnDisconnectEx, const NetAddr &acceptAddress, 00089 const NetAddr &remoteClientAddress); 00090 00091 bool QueueWSARecv(); 00092 void OnWSARecvComplete(int error, u32 bytes); 00093 00094 bool QueueWSASend(TypedOverlapped *sendOv, u32 bytes); 00095 void OnWSASendComplete(int error, u32 bytes); 00096 00097 bool QueueDisconnectEx(); 00098 void OnDisconnectExComplete(int error); 00099 }; 00100 00101 00102 /* 00103 class TCPClient 00104 00105 Object that represents a TCPClient bound to a single port 00106 00107 ValidClient() : Returns true iff the client socket is valid 00108 00109 Connect() : Connects to the given address 00110 DisconnectServer() : Disconnects from the server 00111 PostToServer() : Send a message to the server (will fail if not connected) 00112 00113 OnConnectToServer() : Called when connection is accepted 00114 OnReadFromServer() : Return false to disconnect the server in response to data 00115 OnWriteToServer() : Informs the derived class that data has been sent 00116 OnDisconnectFromServer() : Informs the derived class that the server has disconnected 00117 */ 00118 class TCPClient : public ThreadRefObject 00119 { 00120 friend class ThreadPool; 00121 00122 public: 00123 TCPClient(); 00124 virtual ~TCPClient(); 00125 00126 bool ValidClient(); 00127 00128 bool Connect(const NetAddr &remoteServerAddress); 00129 void DisconnectServer(); 00130 bool PostToServer(void *buffer, u32 bytes); 00131 00132 protected: 00133 virtual void OnConnectToServer() = 0; 00134 virtual bool OnReadFromServer(u8 *data, u32 bytes) = 0; // false = disconnect 00135 virtual void OnWriteToServer(u32 bytes) = 0; 00136 virtual void OnDisconnectFromServer() = 0; 00137 00138 private: 00139 Socket _socket; 00140 TypedOverlapped *_recvOv; 00141 volatile u32 _disconnecting; 00142 bool _ipv6; 00143 00144 private: 00145 bool QueueConnectEx(const NetAddr &remoteServerAddress); 00146 void OnConnectExComplete(int error); 00147 00148 bool QueueWSARecv(); 00149 void OnWSARecvComplete(int error, u32 bytes); 00150 00151 bool QueueWSASend(TypedOverlapped *sendOv, u32 bytes); 00152 void OnWSASendComplete(int error, u32 bytes); 00153 00154 bool QueueDisconnectEx(); 00155 void OnDisconnectExComplete(int error); 00156 }; 00157 00158 00159 /* 00160 class TCPClientQueued 00161 00162 Base class for a TCP client that needs to queue up data for sending before 00163 a connection has been established. e.g. Uplink for a proxy server. 00164 00165 PostQueuedToServer() : Call in OnConnectToServer() to post the queued messages. 00166 */ 00167 class TCPClientQueued : public TCPClient 00168 { 00169 private: 00170 volatile bool _queuing; 00171 00172 Mutex _queueLock; 00173 void *_queueBuffer; 00174 u32 _queueBytes; 00175 00176 protected: 00177 void PostQueuedToServer(); 00178 00179 public: 00180 TCPClientQueued(); 00181 virtual ~TCPClientQueued(); 00182 00183 bool PostToServer(void *buffer, u32 bytes); 00184 }; 00185 00186 00187 /* 00188 class UDPEndpoint 00189 00190 Object that represents a UDP endpoint bound to a single port 00191 */ 00192 class UDPEndpoint : public ThreadRefObject 00193 { 00194 friend class ThreadPool; 00195 00196 public: 00197 UDPEndpoint(); 00198 virtual ~UDPEndpoint(); 00199 00200 bool Valid(); 00201 Port GetPort(); 00202 00203 // Is6() result is only valid AFTER Bind() 00204 CAT_INLINE bool Is6() { return _ipv6; } 00205 00206 // For servers: Bind() with ignoreUnreachable = true ((default)) 00207 // For clients: Bind() with ignoreUnreachable = false and call this 00208 // after the first packet from the server is received. 00209 bool IgnoreUnreachable(); 00210 00211 void Close(); // Invalidates this object 00212 bool Bind(Port port = 0, bool ignoreUnreachable = true); 00213 bool QueueWSARecvFrom(); 00214 00215 // If Is6() == true, the address must be promoted to IPv6 00216 // before calling Post() with addr.PromoteTo6() 00217 bool Post(const NetAddr &addr, void *data, u32 bytes); 00218 00219 protected: 00220 virtual void OnRead(ThreadPoolLocalStorage *tls, const NetAddr &addr, u8 *data, u32 bytes) = 0; // false = close 00221 virtual void OnWrite(u32 bytes) = 0; 00222 virtual void OnClose() = 0; 00223 virtual void OnUnreachable(const NetAddr &addr) {} // Only IP is valid 00224 00225 private: 00226 Socket _socket; 00227 Port _port; 00228 volatile u32 _closing; 00229 bool _ipv6; 00230 00231 private: 00232 bool QueueWSARecvFrom(RecvFromOverlapped *recvOv); 00233 void OnWSARecvFromComplete(ThreadPoolLocalStorage *tls, int error, RecvFromOverlapped *recvOv, u32 bytes); 00234 00235 bool QueueWSASendTo(const NetAddr &addr, TypedOverlapped *sendOv, u32 bytes); 00236 void OnWSASendToComplete(int error, u32 bytes); 00237 }; 00238 00239 00240 } // namespace cat 00241 00242 #endif // CAT_THREAD_POOL_SOCKETS_HPP
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.