Shadowrun: Awakened 29 September 2011 - Build 871
UDPEndpoint.hpp
Go to the documentation of this file.
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.

GNU Lesser General Public License 3 Sourceforge.net