IBR-DTNSuite  0.8
ibrcommon/ibrcommon/net/vsocket.h
Go to the documentation of this file.
00001 /*
00002  * vsocket.h
00003  *
00004  *  Created on: 14.12.2010
00005  *      Author: morgenro
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 {
00034         int __nonlinux_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
00035 
00036         class vsocket_exception : public Exception
00037         {
00038         public:
00039                 vsocket_exception(string error) : Exception(error)
00040                 {};
00041         };
00042 
00043         class vsocket_timeout : public vsocket_exception
00044         {
00045         public:
00046                 vsocket_timeout(string error) : vsocket_exception(error)
00047                 {};
00048         };
00049 
00050         class vsocket_interrupt : public vsocket_exception
00051         {
00052         public:
00053                 vsocket_interrupt(string error) : vsocket_exception(error)
00054                 {};
00055         };
00056 
00057         class vsocket : public ibrcommon::LinkManager::EventCallback
00058         {
00059         public:
00060                 enum Option
00061                 {
00062                         VSOCKET_REUSEADDR = 1 << 0,
00063                         VSOCKET_LINGER = 1 << 1,
00064                         VSOCKET_NODELAY = 1 << 2,
00065                         VSOCKET_BROADCAST = 1 << 3,
00066                         VSOCKET_NONBLOCKING = 1 << 4,
00067                         VSOCKET_MULTICAST = 1 << 5,
00068                         VSOCKET_MULTICAST_V6 = 1 << 6
00069                 };
00070 
00071                 static void set_non_blocking(int socket, bool nonblock = true);
00072 
00073                 vsocket();
00074                 virtual ~vsocket();
00075 
00076                 int bind(const vaddress &address, const int port, unsigned int socktype = SOCK_STREAM);
00077                 void bind(const vinterface &iface, const int port, unsigned int socktype = SOCK_STREAM);
00078                 int bind(const int port, unsigned int socktype = SOCK_STREAM);
00079                 int bind(const ibrcommon::File &file, unsigned int socktype = SOCK_STREAM);
00080 
00081                 void unbind(const vaddress &address, const int port);
00082                 void unbind(const vinterface &iface, const int port);
00083                 void unbind(const int port);
00084                 void unbind(const ibrcommon::File &file);
00085 
00086                 void add(const int fd);
00087 
00088                 const std::list<int> get(const ibrcommon::vinterface &iface, const ibrcommon::vaddress::Family f = vaddress::VADDRESS_UNSPEC);
00089                 const std::list<int> get(const ibrcommon::vaddress::Family f = vaddress::VADDRESS_UNSPEC);
00090 
00091                 void listen(int connections);
00092                 void relisten();
00093 
00094                 void set(const Option &o);
00095                 void unset(const Option &o);
00096 
00097                 void close();
00098                 void shutdown();
00099 
00100                 int fd();
00101 
00102                 void select(std::list<int> &fds, struct timeval *tv = NULL);
00103                 int sendto(const void *buf, size_t n, const ibrcommon::vaddress &address, const unsigned int port);
00104 
00105                 void eventNotify(const LinkManagerEvent &evt);
00106 
00107                 void setEventCallback(ibrcommon::LinkManager::EventCallback *cb);
00108 
00109         private:
00110                 class vbind
00111                 {
00112                 public:
00113                         enum bind_type
00114                         {
00115                                 BIND_ADDRESS,
00116                                 BIND_FILE,
00117                                 BIND_CUSTOM,
00118                                 BIND_ADDRESS_NOPORT
00119                         };
00120 
00121                         const bind_type _type;
00122                         const vaddress _vaddress;
00123                         const int _port;
00124                         const ibrcommon::File _file;
00125                         const ibrcommon::vinterface _interface;
00126 
00127                         int _fd;
00128 
00129                         vbind(int fd);
00130                         vbind(const vaddress &address, unsigned int socktype);
00131                         vbind(const vaddress &address, const int port, unsigned int socktype);
00132                         vbind(const ibrcommon::vinterface &iface, const vaddress &address, unsigned int socktype);
00133                         vbind(const ibrcommon::vinterface &iface, const vaddress &address, const int port, unsigned int socktype);
00134                         vbind(const ibrcommon::File &file, unsigned int socktype);
00135                         virtual ~vbind();
00136 
00137                         void bind();
00138                         void listen(int connections);
00139 
00140                         void set(const vsocket::Option &o);
00141                         void unset(const vsocket::Option &o);
00142 
00143                         void close();
00144                         void shutdown();
00145 
00146                         bool operator==(const vbind &obj) const;
00147 
00148                 private:
00149                         void check_socket_error(const int err) const;
00150                         void check_bind_error(const int err) const;
00151                 };
00152 
00153                 int bind(const vsocket::vbind &b);
00154                 void refresh();
00155                 void interrupt();
00156 
00157                 ibrcommon::Mutex _bind_lock;
00158                 std::list<vsocket::vbind> _binds;
00159                 std::map<vinterface, unsigned int> _portmap;
00160                 std::map<vinterface, unsigned int> _typemap;
00161 
00162                 unsigned int _options;
00163                 bool _interrupt;
00164 
00165                 //bool rebind;
00166                 int _interrupt_pipe[2];
00167 
00168                 ibrcommon::Queue<vbind> _unbind_queue;
00169 
00170                 int _listen_connections;
00171                 ibrcommon::LinkManager::EventCallback *_cb;
00172         };
00173 
00174         int recvfrom(int fd, char* data, size_t maxbuffer, std::string &address);
00175 }
00176 
00177 #endif /* VSOCKET_H_ */