diff options
-rw-r--r-- | anytun.cpp | 24 | ||||
-rw-r--r-- | syncListenSocket.h | 421 | ||||
-rw-r--r-- | syncSocket.cpp | 29 | ||||
-rw-r--r-- | syncSocket.h | 6 |
4 files changed, 467 insertions, 13 deletions
@@ -47,6 +47,11 @@ #include "seqWindow.h" #include "connectionList.h" +#include "Sockets/SocketHandler.h" +#include "syncListenSocket.h" + +#include "syncSocket.h" + #define PAYLOAD_TYPE_TAP 0x6558 #define PAYLOAD_TYPE_TUN 0x0800 @@ -200,12 +205,23 @@ void* sender(void* p) pthread_exit(NULL); } -void* sync_receiver(void* p) +void* syncReceiver(void* p ) { Param* param = reinterpret_cast<Param*>(p); - while(1) + SOCKETS_NAMESPACE::SocketHandler h; + SyncListenSocket<SyncSocket,ConnectionList> l(h,param->cl); + + if (l.Bind(23)) + { + exit(-1); + } + Utility::ResolveLocal(); // resolve local hostname + h.Add(&l); + h.Select(1,0); + while (1) { + h.Select(1,0); } } @@ -310,13 +326,17 @@ int main(int argc, char* argv[]) pthread_create(&senderThread, NULL, sender, &p); pthread_t receiverThread; pthread_create(&receiverThread, NULL, receiver, &p); + pthread_t syncReceiverThread; + pthread_create(&syncReceiverThread, NULL, syncReceiver, &p); int ret = sig.run(); pthread_cancel(senderThread); pthread_cancel(receiverThread); + pthread_cancel(syncReceiverThread); pthread_join(senderThread, NULL); pthread_join(receiverThread, NULL); + pthread_join(syncReceiverThread, NULL); delete src; diff --git a/syncListenSocket.h b/syncListenSocket.h new file mode 100644 index 0000000..359c14d --- /dev/null +++ b/syncListenSocket.h @@ -0,0 +1,421 @@ +/** \file ListenSocket.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_SyncListenSocket_H +#define _SOCKETS_SyncListenSocket_H +#include "Sockets/sockets-config.h" + +#ifdef _WIN32 +#include <stdlib.h> +#else +#include <errno.h> +#endif + +#include "Sockets/ISocketHandler.h" +#include "Sockets/Socket.h" +#include "Sockets/Utility.h" +#include "Sockets/SctpSocket.h" +#include "Sockets/Ipv4Address.h" +#include "Sockets/Ipv6Address.h" +#ifdef ENABLE_EXCEPTIONS +#include "Sockets/Exception.h" +#endif + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/** Binds incoming port number to new Socket class X. + \ingroup basic */ +template <class X,class Y> +class SyncListenSocket : public Socket +{ +public: + /** Constructor. + \param h ISocketHandler reference + \param use_creator Optional use of creator (default true) */ + SyncListenSocket(ISocketHandler& h, Y & y,bool use_creator = true) : Socket(h), m_depth(0), m_creator(NULL),y_(y) + ,m_bHasCreate(false) + { + if (use_creator) + { + m_creator = new X(h,y); + Socket *tmp = m_creator -> Create(); + if (tmp && dynamic_cast<X *>(tmp)) + { + m_bHasCreate = true; + } + if (tmp) + { + delete tmp; + } + } + } + ~SyncListenSocket() { + if (m_creator) + { + delete m_creator; + } + } + + /** Close file descriptor. */ + int Close() { + if (GetSocket() != INVALID_SOCKET) + { + closesocket(GetSocket()); + } + return 0; + } + + /** Bind and listen to any interface. + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(port_t port,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(port); + return Bind(ad, depth); + } + else +#endif +#endif + { + Ipv4Address ad(port); + return Bind(ad, depth); + } + } + + int Bind(SocketAddress& ad,int depth) { +#ifdef USE_SCTP + if (dynamic_cast<SctpSocket *>(m_creator)) + { + return Bind(ad, "sctp", depth); + } +#endif + return Bind(ad, "tcp", depth); + } + + /** Bind and listen to any interface, with optional protocol. + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(port_t port,const std::string& protocol,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(port); + return Bind(ad, protocol, depth); + } + else +#endif +#endif + { + Ipv4Address ad(port); + return Bind(ad, protocol, depth); + } + } + + /** Bind and listen to specific interface. + \param intf Interface hostname + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(const std::string& intf,port_t port,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + else +#endif +#endif + { + Ipv4Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + } + + /** Bind and listen to specific interface. + \param intf Interface hostname + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(const std::string& intf,port_t port,const std::string& protocol,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, protocol, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + else +#endif +#endif + { + Ipv4Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, protocol, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + } + + /** Bind and listen to ipv4 interface. + \param a Ipv4 interface address + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(ipaddr_t a,port_t port,int depth = 20) { + Ipv4Address ad(a, port); +#ifdef USE_SCTP + if (dynamic_cast<SctpSocket *>(m_creator)) + { + return Bind(ad, "sctp", depth); + } +#endif + return Bind(ad, "tcp", depth); + } + /** Bind and listen to ipv4 interface. + \param a Ipv4 interface address + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(ipaddr_t a,port_t port,const std::string& protocol,int depth) { + Ipv4Address ad(a, port); + return Bind(ad, protocol, depth); + } + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Bind and listen to ipv6 interface. + \param a Ipv6 interface address + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(in6_addr a,port_t port,int depth = 20) { + Ipv6Address ad(a, port); +#ifdef USE_SCTP + if (dynamic_cast<SctpSocket *>(m_creator)) + { + return Bind(ad, "sctp", depth); + } +#endif + return Bind(ad, "tcp", depth); + } + /** Bind and listen to ipv6 interface. + \param a Ipv6 interface address + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(in6_addr a,port_t port,const std::string& protocol,int depth) { + Ipv6Address ad(a, port); + return Bind(ad, protocol, depth); + } +#endif +#endif + + /** Bind and listen to network interface. + \param ad Interface address + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(SocketAddress& ad,const std::string& protocol,int depth) { + SOCKET s; + if ( (s = CreateSocket(ad.GetFamily(), SOCK_STREAM, protocol)) == INVALID_SOCKET) + { + return -1; + } + if (bind(s, ad, ad) == -1) + { + Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL); + closesocket(s); +#ifdef ENABLE_EXCEPTIONS + throw Exception("bind() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno)); +#endif + return -1; + } + if (listen(s, depth) == -1) + { + Handler().LogError(this, "listen", Errno, StrError(Errno), LOG_LEVEL_FATAL); + closesocket(s); +#ifdef ENABLE_EXCEPTIONS + throw Exception("listen() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno)); +#endif + return -1; + } + m_depth = depth; + Attach(s); + return 0; + } + + /** Return assigned port number. */ + port_t GetPort() + { + return GetSockPort(); + } + + /** Return listen queue depth. */ + int GetDepth() + { + return m_depth; + } + + /** OnRead on a ListenSocket receives an incoming connection. */ + void OnRead() + { + struct sockaddr sa; + socklen_t sa_len = sizeof(struct sockaddr); + SOCKET a_s = accept(GetSocket(), &sa, &sa_len); + + if (a_s == INVALID_SOCKET) + { + Handler().LogError(this, "accept", Errno, StrError(Errno), LOG_LEVEL_ERROR); + return; + } + if (!Handler().OkToAccept(this)) + { + Handler().LogError(this, "accept", -1, "Not OK to accept", LOG_LEVEL_WARNING); + closesocket(a_s); + return; + } + if (Handler().GetCount() >= FD_SETSIZE) + { + Handler().LogError(this, "accept", (int)Handler().GetCount(), "ISocketHandler fd_set limit reached", LOG_LEVEL_FATAL); + closesocket(a_s); + return; + } + Socket *tmp = m_bHasCreate ? m_creator -> Create() : new X(Handler(),y_); +#ifdef ENABLE_IPV6 + tmp -> SetIpv6( IsIpv6() ); +#endif + tmp -> SetParent(this); + tmp -> Attach(a_s); + tmp -> SetNonblocking(true); + { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (sa_len == sizeof(struct sockaddr_in6)) + { + struct sockaddr_in6 *p = (struct sockaddr_in6 *)&sa; + if (p -> sin6_family == AF_INET6) + { + Ipv6Address ad(p -> sin6_addr,ntohs(p -> sin6_port)); + ad.SetFlowinfo(p -> sin6_flowinfo); +#ifndef _WIN32 + ad.SetScopeId(p -> sin6_scope_id); +#endif + tmp -> SetRemoteAddress(ad); + } + } +#endif +#endif + if (sa_len == sizeof(struct sockaddr_in)) + { + struct sockaddr_in *p = (struct sockaddr_in *)&sa; + if (p -> sin_family == AF_INET) + { + Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port)); + tmp -> SetRemoteAddress(ad); + } + } + } + tmp -> SetConnected(true); + tmp -> Init(); + tmp -> SetDeleteByHandler(true); + Handler().Add(tmp); +#ifdef HAVE_OPENSSL + if (tmp -> IsSSL()) // SSL Enabled socket + { + // %! OnSSLAccept calls SSLNegotiate that can finish in this one call. + // %! If that happens and negotiation fails, the 'tmp' instance is + // %! still added to the list of active sockets in the sockethandler. + // %! See bugfix for this in SocketHandler::Select - don't Set rwx + // %! flags if CloseAndDelete() flag is true. + // %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids + // %! the Add problem altogether, so ignore the above. + // %! (OnSSLAccept does no longer call SSLNegotiate().) + tmp -> OnSSLAccept(); + } + else +#endif + { + tmp -> OnAccept(); + } + } + + /** Please don't use this method. + "accept()" is handled automatically in the OnRead() method. */ + virtual SOCKET Accept(SOCKET socket, struct sockaddr *saptr, socklen_t *lenptr) + { + return accept(socket, saptr, lenptr); + } + + bool HasCreator() { return m_bHasCreate; } + + void OnOptions(int,int,int,SOCKET) { + SetSoReuseaddr(true); + } + +protected: + SyncListenSocket(const SyncListenSocket& s) : Socket(s) {} +private: + SyncListenSocket& operator=(const SyncListenSocket& ) { return *this; } + int m_depth; + X *m_creator; + bool m_bHasCreate; + Y & y_; +}; + + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_SyncListenSocket_H + diff --git a/syncSocket.cpp b/syncSocket.cpp index 066e5e6..dbb1dfb 100644 --- a/syncSocket.cpp +++ b/syncSocket.cpp @@ -1,38 +1,49 @@ #include "Sockets/Utility.h" #include "syncSocket.h" - - -SyncSocket::SyncSocket(ISocketHandler& h) -:TcpSocket(h) +//#include <boost/archive/text_oarchive.hpp> +//#include <boost/archive/text_iarchive.hpp> +#include <sstream> +#include <iostream> +#include <string> +#include "connectionParam.h" + +SyncSocket::SyncSocket(ISocketHandler& h,ConnectionList & cl) +:TcpSocket(h),cl_(cl) { // initial connection timeout setting and number of retries SetConnectTimeout(12); SetConnectionRetry(5); // Also reconnect broken link - SetReconnect(true); +// SetReconnect(true); } bool SyncSocket::OnConnectRetry() { - return true; +// return true; + return false; } void SyncSocket::OnReconnect() { // ... - Send("Welcome back\r\n"); + //Send("Welcome back\r\n"); } void SyncSocket::OnAccept() { - Send("Local hostname : " + Utility::GetLocalHostname() + "\n"); - Send("Local address : " + Utility::GetLocalAddress() + "\n"); + Send( Utility::GetLocalHostname() + "\n"); + Send( Utility::GetLocalAddress() + "\n"); Send("Number of sockets in list : " + Utility::l2string(Handler().GetCount()) + "\n"); Send("\n"); + std::ostringstream sout; +// boost::archive::text_oarchive oa(sout); + ConnectionParam conn = cl_.getConnection(); + // oa << conn; + Send(sout.str()+"\n"); } //void StatusSocket::InitSSLServer() diff --git a/syncSocket.h b/syncSocket.h index 77b8824..52ee6df 100644 --- a/syncSocket.h +++ b/syncSocket.h @@ -3,6 +3,7 @@ #include "Sockets/TcpSocket.h" #include "Sockets/ISocketHandler.h" +#include "connectionList.h" #ifdef SOCKETS_NAMESPACE using namespace SOCKETS_NAMESPACE; @@ -11,7 +12,7 @@ using namespace SOCKETS_NAMESPACE; class SyncSocket : public TcpSocket { public: - SyncSocket(ISocketHandler& ); + SyncSocket(ISocketHandler&,ConnectionList & ); void OnAccept(); @@ -20,7 +21,8 @@ public: // void Init(); // void InitSSLServer(); -//private: +private: + ConnectionList & cl_; // ResumeSocket2& operator=(const ResumeSocket2& ) { return *this; } // assignment operator }; |