IBR-DTNSuite  0.10
socket.h
Go to the documentation of this file.
1 /*
2  * socket.h
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #ifndef IBRCOMMON_SOCKET_H_
23 #define IBRCOMMON_SOCKET_H_
24 
25 #include <ibrcommon/Exceptions.h>
26 #include <ibrcommon/data/File.h>
27 #include <ibrcommon/net/vaddress.h>
29 #include <sstream>
30 #include <string.h>
31 #include <sys/time.h>
32 
33 namespace ibrcommon {
35  {
43  };
44 
45  class socket_exception : public Exception
46  {
47  public:
49  {};
50 
51  socket_exception(string error) : Exception(error)
52  {};
53  };
54 
56  {
57  public:
58  socket_error(socket_error_code code, string error) : socket_exception(error), _code(code)
59  {};
60 
61  socket_error_code code() const { return _code; }
62 
63  private:
64  socket_error_code _code;
65  };
66 
68  {
69  public:
70  socket_raw_error(int error, string description) : socket_exception(description), _errno(error)
71  {
72  std::stringstream ss;
73  ss << error << ": " << socket_exception::what();
74  __what = ss.str();
75  };
76 
77  socket_raw_error(int error) : socket_exception(), _errno(error)
78  {
79  std::stringstream ss;
80  ss << error << ": " << ::strerror(error);
81  __what = ss.str();
82  };
83 
84  virtual ~socket_raw_error() throw()
85  {};
86 
87  virtual const char* what() const throw()
88  {
89  return __what.c_str();
90  }
91 
92  int error() const { return _errno; }
93 
94  private:
95  int _errno;
96  std::string __what;
97  };
98 
103  class basesocket {
104  public:
107 
108  virtual ~basesocket() = 0;
109 
115  virtual void up() throw (socket_exception) = 0;
116 
122  virtual void down() throw (socket_exception) = 0;
123 
128  virtual int fd() const throw (socket_exception);
129 
136  virtual int release() throw (socket_exception);
137 
141  void close() throw (socket_exception);
142  void shutdown(int how) throw (socket_exception);
143 
147  bool ready() const;
148 
153  sa_family_t get_family() const throw (socket_exception);
154  static sa_family_t get_family(int fd) throw (socket_exception);
155 
159  static bool hasSupport(const sa_family_t family, const int type = SOCK_DGRAM, const int protocol = 0) throw ();
160 
161  protected:
166  enum socketstate {
171  };
172 
178  basesocket();
179  basesocket(int fd);
180 
184  void check_socket_error(const int err) const throw (socket_exception);
185  void check_bind_error(const int err, const std::string &msg = "") const throw (socket_exception);
186 
187  void set_blocking_mode(bool val, int fd = -1) const throw (socket_exception);
188  void set_keepalive(bool val, int fd = -1) const throw (socket_exception);
189  void set_linger(bool val, int l = 1, int fd = -1) const throw (socket_exception);
190  void set_reuseaddr(bool val, int fd = -1) const throw (socket_exception);
191  void set_nodelay(bool val, int fd = -1) const throw (socket_exception);
192 
193  void init_socket(const vaddress &addr, int type, int protocol) throw (socket_exception);
194  void init_socket(int domain, int type, int protocol) throw (socket_exception);
195 
196  void bind(int fd, struct sockaddr *addr, socklen_t len) throw (socket_exception);
197 
198  // contains the current socket state
200 
201  // contains the file descriptor if one is available
202  int _fd;
203 
204  // stores the socket family
205  sa_family_t _family;
206  };
207 
212  class clientsocket : public basesocket {
213  public:
215  NO_DELAY = 0,
216  BLOCKING = 1
217  };
218 
219  virtual ~clientsocket() = 0;
220  virtual void up() throw (socket_exception);
221  virtual void down() throw (socket_exception);
222 
223  ssize_t send(const char *data, size_t len, int flags = 0) throw (socket_error);
224  ssize_t recv(char *data, size_t len, int flags = 0) throw (socket_error);
225 
226  void set(CLIENT_OPTION opt, bool val) throw (socket_error);
227 
228  protected:
229  clientsocket();
230  clientsocket(int fd);
231  };
232 
233  class serversocket : public basesocket {
234  public:
236  BLOCKING = 0
237  };
238 
239  virtual ~serversocket() = 0;
240  virtual void up() throw (socket_exception) = 0;
241  virtual void down() throw (socket_exception) = 0;
242 
243  void listen(int connections) throw (socket_exception);
244  virtual clientsocket* accept(ibrcommon::vaddress &addr) throw (socket_exception) = 0;
245 
246  void set(SERVER_OPTION opt, bool val);
247 
248  protected:
249  serversocket();
250  serversocket(int fd);
251 
252  int _accept_fd(ibrcommon::vaddress &addr) throw (socket_exception);
253  };
254 
255  class datagramsocket : public basesocket {
256  public:
257  virtual ~datagramsocket() = 0;
258  virtual void up() throw (socket_exception) = 0;
259  virtual void down() throw (socket_exception) = 0;
260 
261  virtual ssize_t recvfrom(char *buf, size_t buflen, int flags, ibrcommon::vaddress &addr) throw (socket_exception);
262  virtual void sendto(const char *buf, size_t buflen, int flags, const ibrcommon::vaddress &addr) throw (socket_exception);
263 
264  protected:
265  datagramsocket();
266  datagramsocket(int fd);
267  };
268 
272  class filesocket : public clientsocket {
273  public:
274  filesocket(int fd);
275  filesocket(const File &file);
276  virtual ~filesocket();
277  virtual void up() throw (socket_exception);
278  virtual void down() throw (socket_exception);
279 
280  private:
281  const File _filename;
282  };
283 
289  public:
290  fileserversocket(const File &file, int listen = 0);
291  virtual ~fileserversocket();
292  virtual void up() throw (socket_exception);
293  virtual void down() throw (socket_exception);
294 
295  virtual clientsocket* accept(ibrcommon::vaddress &addr) throw (socket_exception);
296 
297  private:
298  void bind(const File &file) throw (socket_exception);
299 
300  private:
301  const File _filename;
302  const int _listen;
303  };
304 
308  class tcpsocket : public clientsocket {
309  public:
310  tcpsocket(int fd);
311  tcpsocket(const vaddress &destination, const timeval *timeout = NULL);
312  virtual ~tcpsocket();
313  virtual void up() throw (socket_exception);
314  virtual void down() throw (socket_exception);
315 
316  private:
317  const vaddress _address;
318  timeval _timeout;
319  };
320 
326  class tcpserversocket : public serversocket {
327  public:
328  tcpserversocket(const int port, int listen = 0);
329  tcpserversocket(const vaddress &address, int listen = 0);
330  virtual ~tcpserversocket();
331  virtual void up() throw (socket_exception);
332  virtual void down() throw (socket_exception);
333 
334  const vaddress& get_address() const;
335 
336  virtual clientsocket* accept(ibrcommon::vaddress &addr) throw (socket_exception);
337 
338  protected:
339  void bind(const vaddress &addr) throw (socket_exception);
340 
341  private:
342  const vaddress _address;
343  const int _listen;
344  };
345 
350  class udpsocket : public datagramsocket {
351  public:
352  udpsocket();
353  udpsocket(const vaddress &address);
354  virtual ~udpsocket();
355  virtual void up() throw (socket_exception);
356  virtual void down() throw (socket_exception);
357 
358  const vaddress& get_address() const;
359 
360  protected:
361  void bind(const vaddress &addr) throw (socket_exception);
362 
364  };
365 
366  class multicastsocket : public udpsocket {
367  public:
368  multicastsocket(const vaddress &address);
369  virtual ~multicastsocket();
370  virtual void up() throw (socket_exception);
371  virtual void down() throw (socket_exception);
372 
373  void join(const vaddress &group, const vinterface &iface) throw (socket_exception);
374  void leave(const vaddress &group, const vinterface &iface) throw (socket_exception);
375 
376  private:
377  void mcast_op(int optname, const vaddress &group, const vinterface &iface) throw (socket_exception);
378  };
379 }
380 
381 #endif /* IBRCOMMON_SOCKET_H_ */