IOEvent.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 
17 #include "IOEvent.hh"
18 //#include "IOEvent.ih"
19 
20 // Custom includes
21 #include <senf/Utils/senfassert.hh>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <linux/if_packet.h>
25 #include <net/ethernet.h> /* the L2 protocols */
26 #include <net/if.h>
27 
28 //#include "IOEvent.mpp"
29 #define prefix_
30 //-/////////////////////////////////////////////////////////////////////////////////////////////////
31 
32 //-/////////////////////////////////////////////////////////////////////////////////////////////////
33 // senf::ppi::IOEvent
34 
35 //-/////////////////////////////////////////////////////////////////////////////////////////////////
36 // private members
37 
38 prefix_ void senf::ppi::IOEvent::v_enable()
39 {
40  if (fd_ != -1)
41  event_.enable();
42 }
43 
44 prefix_ void senf::ppi::IOEvent::v_disable()
45 {
46  if (fd_ != -1)
47  event_.disable();
48 }
49 
50 prefix_ void senf::ppi::IOEvent::cb(int event)
51 {
52  if (SENF_UNLIKELY((event & ~event_.events()) != 0)) {
53  if (event & Err) {
54  int err (0);
55  socklen_t len (sizeof(err));
56  if (::getsockopt(fd_, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
57  err = 0;
58  char buf[1024];
59  sockaddr *addr = reinterpret_cast<sockaddr*>(buf);
60  len = sizeof(buf);
61  std::string msg;
62  if (::getsockname(fd_, addr, &len) == 0) {
63  if (addr->sa_family == AF_PACKET) {
64  sockaddr_ll *sa = reinterpret_cast<sockaddr_ll*>(addr);
65  if (sa->sll_ifindex > 0) {
66  char name[256];
67  ::bzero(name, 256);
68  if (::if_indextoname(sa->sll_ifindex, name))
69  msg = name;
70  else
71  msg = "if_index=" + senf::str(sa->sll_ifindex);
72  } else {
73  msg = "if_index is 0";
74  }
75  } else {
76  msg = "sa_family=" + senf::str(addr->sa_family);
77  }
78  } else {
79  msg = "getsockname() failed";
80  }
81  // ENETDOWN seems to result from a race condition inside SENF. Let's disable events for this FD
82  if (err == ENETDOWN) {
83  SENF_LOG ( (senf::log::IMPORTANT) ("ENETDOWN on fd " << fd_ << " (" << msg << ") received. Disabling event. This might be due to a race condition.") );
84  enabled(false);
85  return;
86  } else {
87  throw ErrorException(fd_, err, msg);
88  }
89  }
90  if (event & Hup)
91  throw HangupException();
92  SENF_ASSERT(false, "Internal failure: IOEvent::cb() called with invalid flag??");
93  } else {
94  IOEventInfo info = { event };
95  callback(info);
96  }
97 }
98 
99 //-/////////////////////////////////////////////////////////////////////////////////////////////////
100 #undef prefix_
101 //#include "IOEvent.mpp"
102 
103 
104 // Local Variables:
105 // mode: c++
106 // fill-column: 100
107 // comment-column: 40
108 // c-file-style: "senf"
109 // indent-tabs-mode: nil
110 // ispell-local-dictionary: "american"
111 // compile-command: "scons -u test"
112 // End:
IOEvent public header.
void callback(EventArg event, ClockService::clock_type time)
Forward event to user callback.
FdEvent & events(int events)
#define prefix_
Definition: IOEvent.cc:29
#define SENF_ASSERT(x, comment)
unspecified_keyword_type name
bool enabled() const
Check, whether the event is currently enabled.
#define SENF_LOG(args)
#define SENF_UNLIKELY(x)