ReadWritePolicy.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
18 #include "ReadWritePolicy.hh"
19 #include "senf/Utils/hexdump.hh"
20 #include "senf/Utils/String.hh"
21 //#include "ReadWritePolicy.ih"
22 
23 // Custom includes
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <unistd.h>
27 #include <errno.h>
28 
29 //#include "ReadWritePolicy.mpp"
30 #define prefix_
31 //-/////////////////////////////////////////////////////////////////////////////////////////////////
32 
33 prefix_ unsigned senf::ReadablePolicy::read(FileHandle & handle, char * buffer,
34  unsigned size)
35 {
36  int rv = -1;
37  do {
38  rv = ::read(handle.fd(), buffer, size);
39  if (rv < 0)
40  switch(errno) {
41  case EINTR:
42  break;
43  case EAGAIN:
44  // This means, the socket is non-blocking an no data was available
45  rv = 0;
46  break;
47  default:
49  }
50  } while (rv<0);
51  return rv;
52 }
53 
54 prefix_ unsigned senf::ReadablePolicy::do_readfrom(FileHandle & handle, char * buffer,
55  unsigned size,
56  struct ::sockaddr * addr, socklen_t * len)
57 {
58  int rv = -1;
59  do {
60  rv = ::recvfrom(handle.fd(),buffer, size, 0, addr, len);
61  if (rv < 0)
62  switch (errno) {
63  case EINTR:
64  break;
65  case EAGAIN:
66  rv = 0;
67  break;
68  default:
69  SENF_THROW_SYSTEM_EXCEPTION("::recvfrom");
70  }
71  } while (rv<0);
72  return rv;
73 }
74 
75 prefix_ unsigned senf::WriteablePolicy::do_write(FileHandle & handle, char const * buffer,
76  unsigned size)
77 {
78  int rv = -1;
79  do {
80  rv = ::write(handle.fd(), buffer, size);
81  if (rv < 0)
82  switch (errno) {
83  case EINTR:
84  continue;
85  case EAGAIN:
86  case ENOBUFS:
87  // According to the man page this should not happen, since packets are just silently being dropped.
88  // It does happen in NetEmu using small TxQueues on WLAN interfaces
89  case ECONNREFUSED:
90  // Writing to a UDP socket seems return this error code if a corresponding ICMP
91  // error code has been received before (at least on linux). This is inconsistent
92  // since I cannot rely on getting ECONNREFUSED. I therefore ignore this error. TCP
93  // sockets will return this error on connect() and not on write(). Therefore we can
94  // unconditionally ignore this error here.
95  rv = 0;
96  break;
97  default:
98  SENF_THROW_SYSTEM_EXCEPTION("::write");
99  }
100  } while (rv<0);
101  return rv;
102 }
103 
104 prefix_ unsigned senf::WriteablePolicy::do_writeto(FileHandle & handle,
105  char const * buffer, unsigned size,
106  struct sockaddr const * addr, socklen_t len)
107 {
108  int rv = -1;
109  do {
110  rv = ::sendto(handle.fd(), buffer, size, 0, addr, len);
111  if (rv < 0)
112  switch (errno) {
113  case EINTR:
114  continue;
115  case ENOTCONN:
116  case ENETDOWN:
117  case ENXIO:
118  // TODO: The below might not be the best solution for all use cases, but it's ok for WiBACK
119  // Pretend that we have written out such frames
120  rv = size;
121  break;
122  case EAGAIN:
123  case ENOBUFS:
124  // According to the man page this should not happen, since packets are just silently being dropped.
125  // It does happen in NetEmu using small TxQueues on WLAN interfaces
126  rv = 0;
127  break;
128  default:
129  std::stringstream a, b;
130  senf::hexdump( reinterpret_cast<char const *>(addr) , reinterpret_cast<char const *>(addr + len), a);
131  senf::hexdump( buffer , buffer + size , b);
132  SENF_THROW_SYSTEM_EXCEPTION("::sendto (" + b.str() + ") to " + a.str());
133  }
134  } while (rv<0);
135  return rv;
136 }
137 
138 //-/////////////////////////////////////////////////////////////////////////////////////////////////
139 #undef prefix_
140 //#include "ReadWritePolicy.mpp"
141 
142 
143 // Local Variables:
144 // mode: c++
145 // fill-column: 100
146 // c-file-style: "senf"
147 // indent-tabs-mode: nil
148 // ispell-local-dictionary: "american"
149 // compile-command: "scons -u test"
150 // comment-column: 40
151 // End:
#define SENF_THROW_SYSTEM_EXCEPTION(desc)
#define prefix_
Basic file handle wrapper.
Definition: FileHandle.hh:102
ReadPolicy and WritePolicy public header.
int fd() const
Return the raw FileHandle.
static unsigned read(FileHandle &handle, char *buffer, unsigned size)
read data from socket