SocketSink.cci
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 
14 /** \file
15  \brief SocketSink inline non-template implementation */
16 
17 // Custom includes
18 #include "SocketSink.hh"
19 #include <senf/Socket/ClientSocketHandle.hh>
20 
21 #define prefix_ inline
22 //-/////////////////////////////////////////////////////////////////////////////////////////////////
23 
24 //-/////////////////////////////////////////////////////////////////////////////////////////////////
25 // senf::ppi::ConnectedDgramWriter
26 
27 prefix_ bool senf::ppi::ConnectedDgramWriter::operator()(Handle & handle,
28  Packet const & packet)
29 {
30  return handle.write(packet.data()) != packet.data().begin();
31 }
32 
33 
34 //-/////////////////////////////////////////////////////////////////////////////////////////////////
35 // senf::ppi::LLSocketWriter
36 
37 prefix_ bool senf::ppi::LLSocketWriter::operator()(Handle & handle,
38  Packet const & packet)
39 {
40  do {
41  if (::write(handle.fd(), packet.data().begin(), packet.size()) >= 0)
42  return true;
43 
44  switch (errno) {
45  case EINTR:
46  break;
47  case ENOTCONN:
48  case ENETDOWN:
49  case ENXIO:
50  // TODO: The below might not be the best solution for all use cases, but it's ok for WiBACK
51  // Pretend that we have written out such frames
52  return true;
53  case EAGAIN:
54  case ENOBUFS:
55  // According to the man page this should not happen, since packets are just silently being dropped.
56  // It does happen in NetEmu using small TxQueues on WLAN interfaces
57  case ECONNREFUSED:
58  // Writing to a UDP socket seems return this error code if a corresponding ICMP
59  // error code has been received before (at least on linux). This is inconsistent
60  // since I cannot rely on getting ECONNREFUSED. I therefore ignore this error. TCP
61  // sockets will return this error on connect() and not on write(). Therefore we can
62  // unconditionally ignore this error here.
63  return false;
64  default:
65  SENF_THROW_SYSTEM_EXCEPTION("::write");
66  }
67  } while (true);
68 }
69 
70 //-/////////////////////////////////////////////////////////////////////////////////////////////////
71 // senf::ppi::TargetLLSocketWriter
72 
73 prefix_ bool senf::ppi::TargetLLSocketWriter::operator()(Handle & handle, EthernetPacket const & packet)
74 {
75  do {
76  target_.protocol(packet->type_length());
77  if (::sendto(handle.fd(), packet.data().begin(), packet.size(), 0, target_.sockaddr_p(), target_.socklen()) >= 0)
78  return true;
79 
80  switch (errno) {
81  case EINTR:
82  break;
83  case ENOTCONN:
84  case ENETDOWN:
85  case ENXIO:
86  // TODO: The below might not be the best solution for all use cases, but it's ok for WiBACK
87  // Pretend that we have written out such frames
88  return true;
89  case EAGAIN:
90  case ENOBUFS:
91  // According to the man page this should not happen, since packets are just silently being dropped.
92  // It does happen in NetEmu using small TxQueues on WLAN interfaces
93  case ECONNREFUSED:
94  // Writing to a UDP socket seems return this error code if a corresponding ICMP
95  // error code has been received before (at least on linux). This is inconsistent
96  // since I cannot rely on getting ECONNREFUSED. I therefore ignore this error. TCP
97  // sockets will return this error on connect() and not on write(). Therefore we can
98  // unconditionally ignore this error here.
99  return false;
100  default:
101  SENF_THROW_SYSTEM_EXCEPTION("::sendto");
102  }
103  } while (true);
104 }
105 
106 
107 //-/////////////////////////////////////////////////////////////////////////////////////////////////
108 #undef prefix_
109 
110 
111 // Local Variables:
112 // mode: c++
113 // fill-column: 100
114 // comment-column: 40
115 // c-file-style: "senf"
116 // indent-tabs-mode: nil
117 // ispell-local-dictionary: "american"
118 // compile-command: "scons -u test"
119 // End: