From 6f5e267d5881db22843cedb9a752e92cce9f01ee Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 9 Jan 2015 11:07:43 +0100 Subject: Implemented LibEvent-based client connections. --- src/OSSupport/Network.h | 188 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 src/OSSupport/Network.h (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h new file mode 100644 index 000000000..447cd457b --- /dev/null +++ b/src/OSSupport/Network.h @@ -0,0 +1,188 @@ + +// Network.h + +// Declares the classes used for the Network API + + + + + +#pragma once + + + + + +/** Interface that provides the methods available on a single TCP connection. */ +class cTCPLink +{ + friend class cNetwork; + +public: + class cCallbacks + { + public: + /** Called when there's data incoming from the remote peer. */ + virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Length) = 0; + + /** Called when the remote end closes the connection. + The link is still available for connection information query (IP / port). + Sending data on the link is not an error, but the data won't be delivered. */ + virtual void OnRemoteClosed(cTCPLink & a_Link) = 0; + + /** Called when an error is detected on the connection. */ + virtual void OnError(cTCPLink & a_Link, int a_ErrorCode) = 0; + }; + typedef SharedPtr cCallbacksPtr; + + + /** Queues the specified data for sending to the remote peer. + Returns true on success, false on failure. Note that this success or failure only reports the queue status, not the actual data delivery. */ + virtual bool Send(const void * a_Data, size_t a_Length) = 0; + + /** Queues the specified data for sending to the remote peer. + Returns true on success, false on failure. Note that this success or failure only reports the queue status, not the actual data delivery. */ + bool Send(const AString & a_Data) + { + return Send(a_Data.data(), a_Data.size()); + } + + /** Returns the IP address of the local endpoint of the connection. */ + virtual AString GetLocalIP(void) const = 0; + + /** Returns the port used by the local endpoint of the connection. */ + virtual UInt16 GetLocalPort(void) const = 0; + + /** Returns the IP address of the remote endpoint of the connection. */ + virtual AString GetRemoteIP(void) const = 0; + + /** Returns the port used by the remote endpoint of the connection. */ + virtual UInt16 GetRemotePort(void) const = 0; + + /** Closes the link gracefully. + The link will keep trying to send the queued data, then it will send the FIN packet. */ + virtual void Close(void) = 0; + + /** Drops the connection without any more processing. + Sends the RST packet, queued outgoing and incoming data is lost. */ + virtual void Drop(void) = 0; + +protected: + /** Callbacks to be used for the various situations. */ + cCallbacksPtr m_Callbacks; + + + /** Creates a new link, with the specified callbacks. */ + cTCPLink(cCallbacksPtr a_Callbacks); +}; + + + + + +/** Interface that provides the methods available on a listening server socket. */ +class cServerHandle +{ + friend class cNetwork; +public: + + /** Stops the server, no more incoming connections will be accepted. */ + virtual void Close(void) = 0; + + /** Returns true if the server has been started correctly and is currently listening for incoming connections. */ + virtual bool IsListening(void) const = 0; +}; +typedef SharedPtr cServerHandlePtr; + + + + + +class cNetwork +{ +public: + /** Callbacks used for connecting to other servers as a client. */ + class cConnectCallbacks + { + public: + /** Called when the Connect call succeeds. + Provides the newly created link that can be used for communication. */ + virtual void OnSuccess(cTCPLink & a_Link) = 0; + + /** Called when the Connect call fails. */ + virtual void OnError(int a_ErrorCode) = 0; + }; + typedef SharedPtr cConnectCallbacksPtr; + + + /** Callbacks used when listening for incoming connections as a server. */ + class cListenCallbacks + { + public: + /** Called when the TCP server created with Listen() accepts an incoming connection. + Provides the newly created Link that can be used for communication. */ + virtual void OnAccepted(cTCPLink & a_Link) = 0; + }; + typedef SharedPtr cListenCallbacksPtr; + + + /** Callbacks used when resolving names to IPs. */ + class cResolveNameCallbacks + { + public: + /** Called when the hostname is successfully resolved into an IP address. */ + virtual void OnNameResolved(const AString & a_Name, const AString & a_IP) = 0; + + /** Called when an error is encountered while resolving. */ + virtual void OnError(int a_ErrorCode) = 0; + }; + typedef SharedPtr cResolveNameCallbacksPtr; + + + /** Queues a TCP connection to be made to the specified host. + Calls one the connection callbacks (success, error) when the connection is successfully established, or upon failure. + The a_LinkCallbacks is passed to the newly created cTCPLink. + Returns true if queueing was successful, false on failure to queue. + Note that the return value doesn't report the success of the actual connection; the connection is established asynchronously in the background. */ + static bool Connect( + const AString & a_Host, + const UInt16 a_Port, + cConnectCallbacksPtr a_ConnectCallbacks, + cTCPLink::cCallbacksPtr a_LinkCallbacks + ); + + + /** Opens up the specified port for incoming connections. + Calls an OnAccepted callback for each incoming connection. + A cTCPLink with the specified link callbacks is created for each connection. + Returns a cServerHandle that can be used to query the operation status and close the server. */ + static cServerHandlePtr Listen( + const UInt16 a_Port, + cListenCallbacksPtr a_ListenCallbacks, + cTCPLink::cCallbacksPtr a_LinkCallbacks + ); + + + /** Queues a DNS query to resolve the specified hostname to IP address. + Calls one of the callbacks when the resolving succeeds, or when it fails. + Returns true if queueing was successful, false if not. + Note that the return value doesn't report the success of the actual lookup; the lookup happens asynchronously on the background. */ + static bool HostnameToIP( + const AString & a_Hostname, + cResolveNameCallbacksPtr a_Callbacks + ); + + + /** Queues a DNS query to resolve the specified IP address to a hostname. + Calls one of the callbacks when the resolving succeeds, or when it fails. + Returns true if queueing was successful, false if not. + Note that the return value doesn't report the success of the actual lookup; the lookup happens asynchronously on the background. */ + static bool IPToHostName( + const AString & a_IP, + cResolveNameCallbacksPtr a_Callbacks + ); +}; + + + + -- cgit v1.2.3 From b8b3409b74e93dd7d1e87f60f498c724e5374f26 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 9 Jan 2015 11:20:19 +0100 Subject: cNetwork: Linux compilation fix. --- src/OSSupport/Network.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 447cd457b..5cca511dc 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -22,6 +22,9 @@ public: class cCallbacks { public: + // Force a virtual destructor for all descendants: + virtual ~cCallbacks() {} + /** Called when there's data incoming from the remote peer. */ virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Length) = 0; @@ -36,6 +39,9 @@ public: typedef SharedPtr cCallbacksPtr; + // Force a virtual destructor for all descendants: + virtual ~cTCPLink() {} + /** Queues the specified data for sending to the remote peer. Returns true on success, false on failure. Note that this success or failure only reports the queue status, not the actual data delivery. */ virtual bool Send(const void * a_Data, size_t a_Length) = 0; @@ -86,6 +92,9 @@ class cServerHandle friend class cNetwork; public: + // Force a virtual destructor for all descendants: + virtual ~cServerHandle() {} + /** Stops the server, no more incoming connections will be accepted. */ virtual void Close(void) = 0; @@ -105,6 +114,9 @@ public: class cConnectCallbacks { public: + // Force a virtual destructor for all descendants: + virtual ~cConnectCallbacks() {} + /** Called when the Connect call succeeds. Provides the newly created link that can be used for communication. */ virtual void OnSuccess(cTCPLink & a_Link) = 0; @@ -119,6 +131,9 @@ public: class cListenCallbacks { public: + // Force a virtual destructor for all descendants: + virtual ~cListenCallbacks() {} + /** Called when the TCP server created with Listen() accepts an incoming connection. Provides the newly created Link that can be used for communication. */ virtual void OnAccepted(cTCPLink & a_Link) = 0; @@ -130,6 +145,9 @@ public: class cResolveNameCallbacks { public: + // Force a virtual destructor for all descendants: + virtual ~cResolveNameCallbacks() {} + /** Called when the hostname is successfully resolved into an IP address. */ virtual void OnNameResolved(const AString & a_Name, const AString & a_IP) = 0; -- cgit v1.2.3 From fde44cba0815f626253c0d352cd0d782eec94328 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 11 Jan 2015 11:21:18 +0100 Subject: cNetwork: Implemented HostnameToIP lookups. --- src/OSSupport/Network.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 5cca511dc..3f60b03a7 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -148,11 +148,18 @@ public: // Force a virtual destructor for all descendants: virtual ~cResolveNameCallbacks() {} - /** Called when the hostname is successfully resolved into an IP address. */ + /** Called when the hostname is successfully resolved into an IP address. + May be called multiple times if an address resolves to multiple addresses. + a_IP may be either an IPv4 or an IPv6 address with their proper formatting. */ virtual void OnNameResolved(const AString & a_Name, const AString & a_IP) = 0; - /** Called when an error is encountered while resolving. */ + /** Called when an error is encountered while resolving. + If an error is reported, the OnFinished() callback is not called. */ virtual void OnError(int a_ErrorCode) = 0; + + /** Called when all the addresses resolved have been reported via the OnNameResolved() callback. + Only called if there was no error reported. */ + virtual void OnFinished(void) = 0; }; typedef SharedPtr cResolveNameCallbacksPtr; -- cgit v1.2.3 From d8ac99a0374b528caca66ad8ecb5fb36f6334e77 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 12 Jan 2015 14:58:52 +0100 Subject: cNetwork: Implemented connection shutdown and close. --- src/OSSupport/Network.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 3f60b03a7..11c45b152 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -66,12 +66,13 @@ public: virtual UInt16 GetRemotePort(void) const = 0; /** Closes the link gracefully. - The link will keep trying to send the queued data, then it will send the FIN packet. */ - virtual void Close(void) = 0; + The link will send any queued outgoing data, then it will send the FIN packet. + The link will still receive incoming data from remote until the remote closes the connection. */ + virtual void Shutdown(void) = 0; /** Drops the connection without any more processing. Sends the RST packet, queued outgoing and incoming data is lost. */ - virtual void Drop(void) = 0; + virtual void Close(void) = 0; protected: /** Callbacks to be used for the various situations. */ @@ -95,7 +96,8 @@ public: // Force a virtual destructor for all descendants: virtual ~cServerHandle() {} - /** Stops the server, no more incoming connections will be accepted. */ + /** Stops the server, no more incoming connections will be accepted. + All current connections will be shut down (cTCPLink::Shutdown()). */ virtual void Close(void) = 0; /** Returns true if the server has been started correctly and is currently listening for incoming connections. */ -- cgit v1.2.3 From 7cddb6237418f2d7ec984cd0d4cbdac7140330b0 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 15 Jan 2015 21:10:14 +0100 Subject: cNetwork: Added an OnError callback for listening servers. The callback receives the error details. --- src/OSSupport/Network.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 11c45b152..cb5badaeb 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -139,6 +139,9 @@ public: /** Called when the TCP server created with Listen() accepts an incoming connection. Provides the newly created Link that can be used for communication. */ virtual void OnAccepted(cTCPLink & a_Link) = 0; + + /** Called when the socket fails to listen on the specified port. */ + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) = 0; }; typedef SharedPtr cListenCallbacksPtr; -- cgit v1.2.3 From c0cb787c101725a649d26de68fca2632c82830ba Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 18 Jan 2015 11:57:16 +0100 Subject: cNetwork: Split the main cpp file into several files. --- src/OSSupport/Network.h | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index cb5badaeb..0452c3b6a 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -80,7 +80,10 @@ protected: /** Creates a new link, with the specified callbacks. */ - cTCPLink(cCallbacksPtr a_Callbacks); + cTCPLink(cCallbacksPtr a_Callbacks): + m_Callbacks(a_Callbacks) + { + } }; @@ -154,7 +157,7 @@ public: virtual ~cResolveNameCallbacks() {} /** Called when the hostname is successfully resolved into an IP address. - May be called multiple times if an address resolves to multiple addresses. + May be called multiple times if a name resolves to multiple addresses. a_IP may be either an IPv4 or an IPv6 address with their proper formatting. */ virtual void OnNameResolved(const AString & a_Name, const AString & a_IP) = 0; @@ -173,7 +176,8 @@ public: Calls one the connection callbacks (success, error) when the connection is successfully established, or upon failure. The a_LinkCallbacks is passed to the newly created cTCPLink. Returns true if queueing was successful, false on failure to queue. - Note that the return value doesn't report the success of the actual connection; the connection is established asynchronously in the background. */ + Note that the return value doesn't report the success of the actual connection; the connection is established asynchronously in the background. + Implemented in TCPLinkImpl.cpp. */ static bool Connect( const AString & a_Host, const UInt16 a_Port, @@ -185,7 +189,8 @@ public: /** Opens up the specified port for incoming connections. Calls an OnAccepted callback for each incoming connection. A cTCPLink with the specified link callbacks is created for each connection. - Returns a cServerHandle that can be used to query the operation status and close the server. */ + Returns a cServerHandle that can be used to query the operation status and close the server. + Implemented in ServerHandleImpl.cpp. */ static cServerHandlePtr Listen( const UInt16 a_Port, cListenCallbacksPtr a_ListenCallbacks, @@ -196,7 +201,8 @@ public: /** Queues a DNS query to resolve the specified hostname to IP address. Calls one of the callbacks when the resolving succeeds, or when it fails. Returns true if queueing was successful, false if not. - Note that the return value doesn't report the success of the actual lookup; the lookup happens asynchronously on the background. */ + Note that the return value doesn't report the success of the actual lookup; the lookup happens asynchronously on the background. + Implemented in HostnameLookup.cpp. */ static bool HostnameToIP( const AString & a_Hostname, cResolveNameCallbacksPtr a_Callbacks @@ -206,7 +212,8 @@ public: /** Queues a DNS query to resolve the specified IP address to a hostname. Calls one of the callbacks when the resolving succeeds, or when it fails. Returns true if queueing was successful, false if not. - Note that the return value doesn't report the success of the actual lookup; the lookup happens asynchronously on the background. */ + Note that the return value doesn't report the success of the actual lookup; the lookup happens asynchronously on the background. + Implemented in IPLookup.cpp. */ static bool IPToHostName( const AString & a_IP, cResolveNameCallbacksPtr a_Callbacks -- cgit v1.2.3 From 64855ed340e76779b99f37fbc866a7f5952e11db Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 20 Jan 2015 11:27:05 +0100 Subject: cNetwork: Added error message to error callbacks. --- src/OSSupport/Network.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 0452c3b6a..3ed9885ec 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -34,7 +34,7 @@ public: virtual void OnRemoteClosed(cTCPLink & a_Link) = 0; /** Called when an error is detected on the connection. */ - virtual void OnError(cTCPLink & a_Link, int a_ErrorCode) = 0; + virtual void OnError(cTCPLink & a_Link, int a_ErrorCode, const AString & a_ErrorMsg) = 0; }; typedef SharedPtr cCallbacksPtr; @@ -127,7 +127,7 @@ public: virtual void OnSuccess(cTCPLink & a_Link) = 0; /** Called when the Connect call fails. */ - virtual void OnError(int a_ErrorCode) = 0; + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) = 0; }; typedef SharedPtr cConnectCallbacksPtr; @@ -163,7 +163,7 @@ public: /** Called when an error is encountered while resolving. If an error is reported, the OnFinished() callback is not called. */ - virtual void OnError(int a_ErrorCode) = 0; + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) = 0; /** Called when all the addresses resolved have been reported via the OnNameResolved() callback. Only called if there was no error reported. */ -- cgit v1.2.3 From 5b4c5cf2befebb78ff2b16955c244e79841648a7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 21 Jan 2015 21:12:11 +0100 Subject: cNetwork: Changed listening API. The link-callbacks for each new accepted link are now received from the OnIncomingConnection listen-callback. --- src/OSSupport/Network.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 3ed9885ec..b9ca377cb 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -139,8 +139,15 @@ public: // Force a virtual destructor for all descendants: virtual ~cListenCallbacks() {} - /** Called when the TCP server created with Listen() accepts an incoming connection. - Provides the newly created Link that can be used for communication. */ + /** Called when the TCP server created with Listen() receives a new incoming connection. + Returns the link callbacks that the server should use for the newly created link. + If a nullptr is returned, the connection is dropped immediately; + otherwise a new cTCPLink instance is created and OnAccepted() is called. */ + virtual cTCPLink::cCallbacksPtr OnIncomingConnection(const AString & a_RemoteIPAddress, UInt16 a_RemotePort) = 0; + + /** Called when the TCP server created with Listen() creates a new link for an incoming connection. + Provides the newly created Link that can be used for communication. + Called right after a successful OnIncomingConnection(). */ virtual void OnAccepted(cTCPLink & a_Link) = 0; /** Called when the socket fails to listen on the specified port. */ @@ -180,7 +187,7 @@ public: Implemented in TCPLinkImpl.cpp. */ static bool Connect( const AString & a_Host, - const UInt16 a_Port, + UInt16 a_Port, cConnectCallbacksPtr a_ConnectCallbacks, cTCPLink::cCallbacksPtr a_LinkCallbacks ); @@ -192,9 +199,8 @@ public: Returns a cServerHandle that can be used to query the operation status and close the server. Implemented in ServerHandleImpl.cpp. */ static cServerHandlePtr Listen( - const UInt16 a_Port, - cListenCallbacksPtr a_ListenCallbacks, - cTCPLink::cCallbacksPtr a_LinkCallbacks + UInt16 a_Port, + cListenCallbacksPtr a_ListenCallbacks ); -- cgit v1.2.3 From dbf7f13bd414daea5e787da2543df186dc465c34 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 22 Jan 2015 13:00:32 +0100 Subject: cNetwork: Added link creation callback. This allows the callback classes to store the link inside them and use it internally later on, mainly for sending data. --- src/OSSupport/Network.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index b9ca377cb..85c7c5dcb 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -13,6 +13,14 @@ +// fwd: +class cTCPLink; +typedef SharedPtr cTCPLinkPtr; + + + + + /** Interface that provides the methods available on a single TCP connection. */ class cTCPLink { @@ -25,16 +33,20 @@ public: // Force a virtual destructor for all descendants: virtual ~cCallbacks() {} + /** Called when the cTCPLink for the connection is created. + The callback may store the cTCPLink instance for later use, but it should remove it in OnError(), OnRemoteClosed() or right after Close(). */ + virtual void OnLinkCreated(cTCPLinkPtr a_Link) = 0; + /** Called when there's data incoming from the remote peer. */ - virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Length) = 0; + virtual void OnReceivedData(const char * a_Data, size_t a_Length) = 0; /** Called when the remote end closes the connection. The link is still available for connection information query (IP / port). Sending data on the link is not an error, but the data won't be delivered. */ - virtual void OnRemoteClosed(cTCPLink & a_Link) = 0; + virtual void OnRemoteClosed(void) = 0; /** Called when an error is detected on the connection. */ - virtual void OnError(cTCPLink & a_Link, int a_ErrorCode, const AString & a_ErrorMsg) = 0; + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) = 0; }; typedef SharedPtr cCallbacksPtr; -- cgit v1.2.3 From 9014bdfa3233dac70274b27eb40df3739b6f49eb Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 22 Jan 2015 22:49:37 +0100 Subject: cNetwork: Renamed callback to OnConnected() --- src/OSSupport/Network.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/OSSupport/Network.h') diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 85c7c5dcb..cdf6ba0e9 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -16,6 +16,10 @@ // fwd: class cTCPLink; typedef SharedPtr cTCPLinkPtr; +typedef std::vector cTCPLinkPtrs; +class cServerHandle; +typedef SharedPtr cServerHandlePtr; +typedef std::vector cServerHandlePtrs; @@ -118,7 +122,6 @@ public: /** Returns true if the server has been started correctly and is currently listening for incoming connections. */ virtual bool IsListening(void) const = 0; }; -typedef SharedPtr cServerHandlePtr; @@ -136,7 +139,7 @@ public: /** Called when the Connect call succeeds. Provides the newly created link that can be used for communication. */ - virtual void OnSuccess(cTCPLink & a_Link) = 0; + virtual void OnConnected(cTCPLink & a_Link) = 0; /** Called when the Connect call fails. */ virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) = 0; -- cgit v1.2.3