interreality.org [VOS]
[Home] [About]
[Screenshots]
[Download]
[News]
[Community]
[Documentation] [Manual]
[Bugs & Requests] [Wiki]

/home/tetron/hack/vos/libs/vos/vip/socketmultiplexer.hh

Go to the documentation of this file.
00001 #ifndef _VIP_SOCKETMULTIPLEXER_HH_
00002 #define _VIP_SOCKETMULTIPLEXER_HH_
00003 
00004 #include <vos/vip/vipdefs.hh>
00005 
00006 #ifdef HAVE_SYS_SOCKET_H
00007 #include <sys/socket.h>
00008 #endif
00009 
00010 #ifdef HAVE_NETDB_H
00011 #include <netdb.h>
00012 #endif
00013 
00014 #ifdef HAVE_NETINET_IN_H
00015 #include <netinet/in.h>
00016 #endif
00017 
00018 #ifdef HAVE_SYS_TIME_H
00019 #include <sys/time.h>
00020 #endif
00021 
00022 #include <iostream>
00023 #include <string>
00024 #include <vector>
00025 #include <map>
00026 #include <deque>
00027 
00028 #include <boost/thread/thread.hpp>
00029 #include <boost/thread/condition.hpp>
00030 
00031 #include <vos/vutil/structpack.hh>
00032 #include <vos/vutil/refcount.hh>
00033 
00034 #include <vos/vip/connection.hh>
00035 
00036 namespace VIP {
00037     struct SockaddrWrapper
00038     {
00039         sockaddr_in sa;
00040         SockaddrWrapper(struct sockaddr_in* si)
00041             {
00042                 memcpy(&sa, si, sizeof(sockaddr_in));
00043             }
00044         SockaddrWrapper(struct sockaddr_in& si)
00045             {
00046                 memcpy(&sa, &si, sizeof(sockaddr_in));
00047             }
00048         SockaddrWrapper(const SockaddrWrapper& sw)
00049             {
00050                 memcpy(&sa, &sw.sa, sizeof(sockaddr_in));
00051             }
00052     };
00053 
00054     class SockaddrCmp
00055     {
00056     public:
00057         inline bool operator()(const SockaddrWrapper& a,
00058                                const SockaddrWrapper& b) const
00059             {
00060                 if(ntohl(a.sa.sin_addr.s_addr) > ntohl(b.sa.sin_addr.s_addr)) {
00061                     return true;
00062                 } else {
00063                     if(ntohl(a.sa.sin_addr.s_addr) < ntohl(b.sa.sin_addr.s_addr)) {
00064                         return false;
00065                     } else {
00066                         return (ntohs(a.sa.sin_port) > ntohs(b.sa.sin_port));
00067                     }
00068                 }
00069             }
00070     };
00071 
00072     struct SocketProcessorThread;
00073 
00074     class VIP_API NewConnectionCallback
00075     {
00076     public:
00077         virtual ~NewConnectionCallback() { }
00078 
00079         virtual void notifyNewConnection(VIP::Connection* m, bool inbound) = 0;
00080     };
00081 
00082     /** @class PortBindingError socketmultiplexer.hh vos/vip/socketmultiplexer.hh
00083         @ingroup libvip
00084     */
00085     class VIP_API PortBindingError : public std::runtime_error
00086     {
00087     public:
00088         PortBindingError(const std::string& s) : std::runtime_error(s) { };
00089     };
00090 
00091     /** @class HostnameError socketmultiplexer.hh vos/vip/socketmultiplexer.hh
00092         @ingroup libvip
00093     */
00094     class VIP_API HostnameError : public std::runtime_error
00095     {
00096     public:
00097         HostnameError(const std::string& s) : std::runtime_error(s) { };
00098     };
00099 
00100     class VIP_API SocketMultiplexer : public VUtil::RefCounted
00101     {
00102     private:
00103         int skt;
00104         boost::mutex connections_mutex;
00105         std::map<SockaddrWrapper, VUtil::vRef<Connection>, SockaddrCmp> connections;
00106         NewConnectionCallback* callback;
00107 
00108         void setupNewConnection(uint8_t* buf, int sz,
00109                                 struct sockaddr_in* from);
00110 
00111     public:
00112         SocketMultiplexer(short int port);
00113         VUtil::vRef<Connection> makeConnection(const std::string& hostname,
00114                                                uint16_t port);
00115 
00116         void setCallback(NewConnectionCallback* cb) { callback = cb; }
00117 
00118         void handlePacket(uint8_t* buf, int ret, sockaddr_in* from);
00119 
00120         int getSocket() { return skt; }
00121 
00122         void removeConnection(struct sockaddr_in* c);
00123     };
00124 }
00125 
00126 #endif