00001
00002
00003
00004
00005
00006
00007
00008 #ifndef VSOCKET_H_
00009 #define VSOCKET_H_
00010
00011 #include <ibrcommon/data/File.h>
00012 #include "ibrcommon/net/LinkManager.h"
00013 #include <ibrcommon/net/vinterface.h>
00014 #include <ibrcommon/net/vaddress.h>
00015 #include <ibrcommon/thread/Mutex.h>
00016 #include <ibrcommon/thread/Thread.h>
00017 #include <ibrcommon/thread/Queue.h>
00018 #include <string>
00019 #include <list>
00020 #include <set>
00021
00022 namespace ibrcommon
00023 {
00024 class vsocket_exception : public Exception
00025 {
00026 public:
00027 vsocket_exception(string error) : Exception(error)
00028 {};
00029 };
00030
00031 class vsocket_timeout : public vsocket_exception
00032 {
00033 public:
00034 vsocket_timeout(string error) : vsocket_exception(error)
00035 {};
00036 };
00037
00038 class vsocket_interrupt : public vsocket_exception
00039 {
00040 public:
00041 vsocket_interrupt(string error) : vsocket_exception(error)
00042 {};
00043 };
00044
00045 class vsocket : public ibrcommon::LinkManager::EventCallback
00046 {
00047
00048 friend void interrupt(ibrcommon::vsocket &sock, ibrcommon::Thread &th);
00049 friend void select(ibrcommon::vsocket &sock, std::list<int> &fds, struct timespec *tv);
00050 friend int sendto(ibrcommon::vsocket &sock, const void *buf, size_t n, const ibrcommon::vaddress &address, const unsigned int port);
00051
00052 public:
00053 enum Option
00054 {
00055 VSOCKET_REUSEADDR = 1 << 0,
00056 VSOCKET_LINGER = 1 << 1,
00057 VSOCKET_NODELAY = 1 << 2,
00058 VSOCKET_BROADCAST = 1 << 3,
00059 VSOCKET_NONBLOCKING = 1 << 4,
00060 VSOCKET_MULTICAST = 1 << 5,
00061 VSOCKET_MULTICAST_V6 = 1 << 6
00062 };
00063
00064 vsocket();
00065 virtual ~vsocket();
00066
00067 int bind(const vaddress &address, const int port, unsigned int socktype = SOCK_STREAM);
00068 void bind(const vinterface &iface, const int port, unsigned int socktype = SOCK_STREAM);
00069 int bind(const int port, unsigned int socktype = SOCK_STREAM);
00070 int bind(const ibrcommon::File &file, unsigned int socktype = SOCK_STREAM);
00071
00072 void unbind(const vaddress &address, const int port);
00073 void unbind(const vinterface &iface, const int port);
00074 void unbind(const int port);
00075 void unbind(const ibrcommon::File &file);
00076
00077 void add(const int fd);
00078
00079 const std::list<int> get(const ibrcommon::vinterface &iface, const ibrcommon::vaddress::Family f = vaddress::VADDRESS_UNSPEC);
00080 const std::list<int> get(const ibrcommon::vaddress::Family f = vaddress::VADDRESS_UNSPEC);
00081
00082 void listen(int connections);
00083 void relisten();
00084
00085 void set(const Option &o);
00086 void unset(const Option &o);
00087
00088 void close();
00089 void shutdown();
00090
00091 int fd();
00092
00093 void eventNotify(const LinkManagerEvent &evt);
00094
00095 void setEventCallback(ibrcommon::LinkManager::EventCallback *cb);
00096
00097 private:
00098 class vbind
00099 {
00100 public:
00101 enum bind_type
00102 {
00103 BIND_ADDRESS,
00104 BIND_FILE,
00105 BIND_CUSTOM,
00106 BIND_ADDRESS_NOPORT
00107 };
00108
00109 const bind_type _type;
00110 const vaddress _vaddress;
00111 const int _port;
00112 const ibrcommon::File _file;
00113 const ibrcommon::vinterface _interface;
00114
00115 int _fd;
00116
00117 vbind(int fd);
00118 vbind(const vaddress &address, unsigned int socktype);
00119 vbind(const vaddress &address, const int port, unsigned int socktype);
00120 vbind(const ibrcommon::vinterface &iface, const vaddress &address, unsigned int socktype);
00121 vbind(const ibrcommon::vinterface &iface, const vaddress &address, const int port, unsigned int socktype);
00122 vbind(const ibrcommon::File &file, unsigned int socktype);
00123 virtual ~vbind();
00124
00125 void bind();
00126 void listen(int connections);
00127
00128 void set(const vsocket::Option &o);
00129 void unset(const vsocket::Option &o);
00130
00131 void close();
00132 void shutdown();
00133
00134 bool operator==(const vbind &obj) const;
00135
00136 private:
00137 void check_socket_error(const int err) const;
00138 void check_bind_error(const int err) const;
00139 };
00140
00141 static void set_non_blocking(int);
00142
00143 int bind(const vsocket::vbind &b);
00144 void refresh();
00145
00146 ibrcommon::Mutex _bind_lock;
00147 std::list<vsocket::vbind> _binds;
00148 std::map<vinterface, unsigned int> _portmap;
00149 std::map<vinterface, unsigned int> _typemap;
00150
00151 unsigned int _options;
00152 bool _interrupt;
00153
00154
00155 int _interrupt_pipe[2];
00156
00157 ibrcommon::Queue<vbind> _unbind_queue;
00158
00159 int _listen_connections;
00160 ibrcommon::LinkManager::EventCallback *_cb;
00161 };
00162
00169 void select(ibrcommon::vsocket &sock, std::list<int> &fds, struct timespec *tv = NULL);
00170 void interrupt(ibrcommon::vsocket &sock, ibrcommon::Thread &th);
00171 void sighandler_poll(int sig);
00172
00173 int sendto(ibrcommon::vsocket &sock, const void *buf, size_t n, const ibrcommon::vaddress &address, const unsigned int port);
00174
00175 int recvfrom(int fd, char* data, size_t maxbuffer, std::string &address);
00176 }
00177
00178 #endif