blob: 080d169f6b1b1aba54a2cd69a87a5ab3f75abd24 [file] [log] [blame]
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2018 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 *
21 * @author Davide Pesavento <davide.pesavento@lip6.fr>
22 */
23
24#ifndef NDN_NET_NETLINK_SOCKET_HPP
25#define NDN_NET_NETLINK_SOCKET_HPP
26
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040027#include "../network-monitor.hpp"
Davide Pesavento10774992018-08-19 18:47:50 -040028#include "../../util/signal/signal.hpp"
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040029
30#include <boost/asio/posix/stream_descriptor.hpp>
Davide Pesaventodc5bb962018-08-12 23:40:38 -040031#include <map>
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040032#include <vector>
33
Davide Pesavento474c3b22018-08-25 16:24:43 -040034#ifndef NDN_CXX_HAVE_NETLINK
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040035#error "This file should not be included ..."
36#endif
37
38namespace ndn {
39namespace net {
40
41class NetlinkMessage;
42
43class NetlinkSocket : noncopyable
44{
45public:
46 using Error = NetworkMonitor::Error;
47 using MessageCallback = std::function<void(const NetlinkMessage&)>;
48
49 void
50 joinGroup(int group);
51
Davide Pesaventodc5bb962018-08-12 23:40:38 -040052 void
53 registerNotificationCallback(MessageCallback cb);
54
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040055protected:
56 explicit
57 NetlinkSocket(boost::asio::io_service& io);
58
59 ~NetlinkSocket();
60
61 void
62 open(int protocol);
63
64 void
Davide Pesaventodc5bb962018-08-12 23:40:38 -040065 registerRequestCallback(uint32_t seq, MessageCallback cb);
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040066
Davide Pesavento10774992018-08-19 18:47:50 -040067 virtual std::string
68 nlmsgTypeToString(uint16_t type) const;
69
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040070private:
71 void
72 asyncWait();
73
74 void
75 receiveAndValidate();
76
77protected:
78 shared_ptr<boost::asio::posix::stream_descriptor> m_sock; ///< netlink socket descriptor
79 uint32_t m_pid; ///< port ID of this socket
80 uint32_t m_seqNum; ///< sequence number of the last netlink request sent to the kernel
81
82private:
83 std::vector<uint8_t> m_buffer; ///< buffer for netlink messages from the kernel
Davide Pesaventodc5bb962018-08-12 23:40:38 -040084 std::map<uint32_t, MessageCallback> m_pendingRequests; ///< request sequence number => callback
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040085};
86
Davide Pesavento10774992018-08-19 18:47:50 -040087class RtnlSocket final : public NetlinkSocket
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -040088{
89public:
90 explicit
91 RtnlSocket(boost::asio::io_service& io);
92
93 void
94 open();
95
96 void
Davide Pesaventodc5bb962018-08-12 23:40:38 -040097 sendDumpRequest(uint16_t nlmsgType, MessageCallback cb);
Davide Pesavento10774992018-08-19 18:47:50 -040098
99protected:
100 std::string
101 nlmsgTypeToString(uint16_t type) const final;
102};
103
104class GenlSocket;
105
106class GenlFamilyResolver : noncopyable
107{
108public:
109 GenlFamilyResolver(std::string familyName, GenlSocket& socket);
110
111 util::Signal<GenlFamilyResolver, uint16_t> onResolved;
112 util::Signal<GenlFamilyResolver> onError;
113
114private:
115 void
116 asyncResolve();
117
118 void
119 handleResolve(const NetlinkMessage& nlmsg);
120
121private:
122 GenlSocket& m_sock;
123 std::string m_family;
124};
125
126class GenlSocket final : public NetlinkSocket
127{
128public:
129 explicit
130 GenlSocket(boost::asio::io_service& io);
131
132 void
133 open();
134
135 void
136 sendRequest(const std::string& familyName, uint8_t command,
137 const void* payload, size_t payloadLen,
138 MessageCallback messageCb, std::function<void()> errorCb);
139
140 void
141 sendRequest(uint16_t familyId, uint8_t command,
142 const void* payload, size_t payloadLen,
143 MessageCallback messageCb);
144
145protected:
146 std::string
147 nlmsgTypeToString(uint16_t type) const final;
148
149private:
150 std::map<std::string, uint16_t> m_cachedFamilyIds; ///< family name => family id
151 std::map<std::string, GenlFamilyResolver> m_familyResolvers; ///< family name => resolver instance
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -0400152};
153
154} // namespace net
155} // namespace ndn
156
157#endif // NDN_NET_NETLINK_SOCKET_HPP