/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
00083
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
00092
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