IPv6 support
Stefan Schuermans

Stefan Schuermans commited on 2013-12-30 13:58:19
Showing 15 changed files, with 702 additions and 0 deletions.

... ...
@@ -0,0 +1,63 @@
1
+<html>
2
+  <head>
3
+    <title>Blinker - UDPv6 Phone Connector</title>
4
+  </head>
5
+  <body>
6
+    <h1>Blinker - UDPv6 Phone Connector</h1>
7
+    <p>
8
+      The UDPv6 phone connector module provides an interface between an
9
+      external phone interface (using EBIP protocol) and the internal
10
+      operator connections.
11
+      The calls coming in over EBIP, can be accepted depedning on the
12
+      called number and forwarded to different modules over operator
13
+      connections.
14
+    </p>
15
+    <h2>Configuration</h2>
16
+    <p>
17
+      The configuration of the UDPv6 phone connector module with name
18
+      <code>NAME</code> is located in the <code>udp4phones/NAME</code>
19
+      subdirectory.
20
+    </p>
21
+    <h3>Bind Address</h3>
22
+    <p>
23
+      The file <code>bind</code> contains the local address to bind to.
24
+      It must contain the IP address and the port, i.e. a string
25
+      <code>&lt;IP&gt;:&lt;port&gt;</code> (hostnames are not supported).
26
+      If the local address should be determined automatically, the file
27
+      can contain <code>[::]:0</code>.
28
+    </p>
29
+    <h3>Server Address</h3>
30
+    <p>
31
+      The file <code>server</code> contains the address of the EBIP server
32
+      as a string <code>&lt;IP&gt;:&lt;port&gt;</code>
33
+      (hostnames are not supported).
34
+      <br>
35
+      The phone connector module will register with this server and
36
+      accept incoming calls.
37
+    </p>
38
+    <h3>Extensions / Phone Numbers</h3>
39
+    <p>
40
+      The virtual extensions (i.e. phone numbers) that can be called via EBIP
41
+      are configured in the subdirectory <code>extensions</code>.
42
+      <br>
43
+      Each extension is configured in its own subdirectory.
44
+      E.g. the configuration for the extension with the phone number
45
+      <code>12345678</code> resides in the subdirectory
46
+      <code>extensions/12345678</code>.
47
+    </p>
48
+    <p>
49
+      The configuration inside an extension consists of the following
50
+      settings:
51
+    </p>
52
+    <h4>Module</h4>
53
+    <p>
54
+      The file <code>module</code> contains the name of the module to
55
+      contact via an operator connection if the extension is called.
56
+      The module name consists of two parts: <code>CLASS/NAME</class>
57
+      E.g. to connect to the operator connection printer named
58
+      <code>debug</code>, the file has to contain
59
+      <code>opprinters/debug</code> as module name.
60
+    </p>
61
+  </body>
62
+</html>
63
+
... ...
@@ -0,0 +1,54 @@
1
+<html>
2
+  <head>
3
+    <title>Blinker - UDPv6 Receiver</title>
4
+  </head>
5
+  <body>
6
+    <h1>Blinker - UDPv6 Receiver</h1>
7
+    <p>
8
+      The UDPv6 receiver module reeceives a stream using UDP version 4 across
9
+      a network.
10
+      It supports the static and dynamic variants of the BLP, EBLP and MCUF
11
+      protocols.
12
+    </p>
13
+    <h2>Configuration</h2>
14
+    <p>
15
+      The configuration of the UDPv6 receiver module with name
16
+      <code>NAME</code> is located in the <code>udp4receivers/NAME</code>
17
+      subdirectory.
18
+    </p>
19
+    <h3>Output Stream</h3>
20
+    <p>
21
+      The file <code>outstream</code> contains the name of the stream to
22
+      write the received network stream to.
23
+    </p>
24
+    <h3>Protocol</h3>
25
+    <p>
26
+      The protocol to use is configured in the file <code>protocol</code>.
27
+      It can contain the string <code>blp</code>, <code>eblp</code> or
28
+      <code>mcuf</code> to select the BLP, EBLP or MCUF protocol respectively.
29
+      If the file is not present, all protocols are accepted.
30
+    </p>
31
+    <h3>Bind Address</h3>
32
+    <p>
33
+      The file <code>bind</code> contains the local address to bind to.
34
+      It must contain the IP address and the port, i.e. a string
35
+      <code>&lt;IP&gt;:&lt;port&gt;</code> (hostnames are not supported).
36
+      If the local address should be determined automatically, the file
37
+      can contain <code>[::]:0</code>.
38
+    </p>
39
+    <h3>Source Address</h3>
40
+    <p>
41
+      The file <code>source</code> contains the source address
42
+      as a string <code>&lt;IP&gt;:&lt;port&gt;</code>
43
+      (hostnames are not supported).
44
+      <br>
45
+      If the source address file exists, only a stream from the specified
46
+      address is accepted.
47
+      Otherwise, the stream can be sent from any address.
48
+      <br>
49
+      If both the source address and the protocol are given, dynamic
50
+      stream request packets are sent to the source address.
51
+    </p>
52
+  </body>
53
+</html>
54
+
... ...
@@ -0,0 +1,60 @@
1
+<html>
2
+  <head>
3
+    <title>Blinker - UDPv6 Sender</title>
4
+  </head>
5
+  <body>
6
+    <h1>Blinker - UDPv6 Sender</h1>
7
+    <p>
8
+      The UDPv6 sender module sends a stream using UDP version 4 across
9
+      a network.
10
+      It supports the static and dynamic variants of the BLP, EBLP and MCUF
11
+      protocols.
12
+    </p>
13
+    <h2>Configuration</h2>
14
+    <p>
15
+      The configuration of the UDPv6 sender module with name <code>NAME</code>
16
+      is located in the <code>udp4senders/NAME</code> subdirectory.
17
+    </p>
18
+    <h3>Input Stream</h3>
19
+    <p>
20
+      The file <code>instream</code> contains the name of the stream to
21
+      read.
22
+      The frames received from this stream are sent over the network.
23
+    </p>
24
+    <h3>Protocol</h3>
25
+    <p>
26
+      The protocol to use is configured in the file <code>protocol</code>.
27
+      It can contain the string <code>blp</code>, <code>eblp</code> or
28
+      <code>mcuf</code> to select the BLP, EBLP or MCUF protocol respectively.
29
+    </p>
30
+    <h3>Bind Address</h3>
31
+    <p>
32
+      The file <code>bind</code> contains the local address to bind to.
33
+      It must contain the IP address and the port, i.e. a string
34
+      <code>&lt;IP&gt;:&lt;port&gt;</code> (hostnames are not supported).
35
+      If the local address should be determined automatically, the file
36
+      can contain <code>[::]:0</code>.
37
+    </p>
38
+    <h3>Static Destinations</h3>
39
+    <p>
40
+      Static destinations to supply with a network stream in the configured
41
+      protocol can be configured in the subdirectory <code>destinations</code>.
42
+      <br>
43
+      Each static destination is configured in an own subdirectory.
44
+      E.g. the configuration for a static destination with name
45
+      <code>local</code> resides in the subdirectory
46
+      <code>destinations/local</code>.
47
+    </p>
48
+    <p>
49
+      The configuration inside a static destination consists of the following
50
+      settings:
51
+    </p>
52
+    <h4>Destination Address</h4>
53
+    <p>
54
+      The file <code>addr</code> contains the destination address
55
+      as a string <code>&lt;IP&gt;:&lt;port&gt;</code>
56
+      (hostnames are not supported).
57
+    </p>
58
+  </body>
59
+</html>
60
+
... ...
@@ -0,0 +1,156 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include <arpa/inet.h>
7
+#include <netinet/in.h>
8
+#include <sstream>
9
+#include <stdlib.h>
10
+#include <string>
11
+#include <string.h>
12
+#include <sys/socket.h>
13
+#include <sys/types.h>
14
+
15
+#include "Udp6Addr.h"
16
+
17
+namespace Blinker {
18
+
19
+/// constructor
20
+Udp6Addr::Udp6Addr()
21
+{
22
+  m_addr.sin6_family = AF_INET6;
23
+  m_addr.sin6_port = htons(0);
24
+  inet_pton(AF_INET6, "::", &m_addr.sin6_addr);
25
+}
26
+
27
+/// virtual destructor
28
+Udp6Addr::~Udp6Addr()
29
+{
30
+}
31
+
32
+/// comparison
33
+//@{
34
+
35
+int Udp6Addr::compare(const Udp6Addr &that) const
36
+{
37
+  if (m_addr.sin6_family < that.m_addr.sin6_family)
38
+    return -1;
39
+  if (m_addr.sin6_family > that.m_addr.sin6_family)
40
+    return 1;
41
+  int cmp = memcmp(&m_addr.sin6_addr, &that.m_addr.sin6_addr,
42
+                   sizeof(m_addr.sin6_addr));
43
+  if (cmp != 0)
44
+    return cmp;
45
+  if (ntohs(m_addr.sin6_port) < ntohs(that.m_addr.sin6_port))
46
+    return -1;
47
+  if (ntohs(m_addr.sin6_port) > ntohs(that.m_addr.sin6_port))
48
+    return 1;
49
+  return 0;
50
+}
51
+
52
+bool Udp6Addr::operator==(const Udp6Addr &that) const
53
+{
54
+  return compare(that) == 0;
55
+}
56
+
57
+bool Udp6Addr::operator!=(const Udp6Addr &that) const
58
+{
59
+  return compare(that) != 0;
60
+}
61
+
62
+bool Udp6Addr::operator<(const Udp6Addr &that) const
63
+{
64
+  return compare(that) < 0;
65
+}
66
+
67
+bool Udp6Addr::operator>(const Udp6Addr &that) const
68
+{
69
+  return compare(that) > 0;
70
+}
71
+
72
+bool Udp6Addr::operator<=(const Udp6Addr &that) const
73
+{
74
+  return compare(that) <= 0;
75
+}
76
+
77
+bool Udp6Addr::operator>=(const Udp6Addr &that) const
78
+{
79
+  return compare(that) >= 0;
80
+}
81
+
82
+//@}
83
+
84
+/// return address family
85
+int Udp6Addr::getFamily() const
86
+{
87
+  return AF_INET6;
88
+}
89
+
90
+/// return port (use this function only if absolutely necessary)
91
+int Udp6Addr::getPort() const
92
+{
93
+  return ntohs(m_addr.sin6_port);
94
+}
95
+
96
+/// set port (use this function only if absolutely necessary)
97
+void Udp6Addr::setPort(int port)
98
+{
99
+  m_addr.sin6_port = htons(port);
100
+}
101
+
102
+/**
103
+ * @brief parse from string format
104
+ * @param[in] str string format
105
+ * @return if parsing was successful
106
+ */
107
+bool Udp6Addr::fromStr(const std::string &str)
108
+{
109
+  std::string::size_type posBraceColon;
110
+  std::string strIp, strPort;
111
+  struct in6_addr iaIp;
112
+  unsigned long iPort;
113
+  const char *szPort;
114
+  char *szPortEnd;
115
+
116
+  // split address into IP and port
117
+  if (str.length() < 1 || str.at(0) != '[')
118
+    return false;
119
+  posBraceColon = str.find("]:");
120
+  if (posBraceColon == std::string::npos)
121
+    return false;
122
+  strIp = str.substr(1, posBraceColon - 1);
123
+  strPort = str.substr(posBraceColon + 2);
124
+
125
+  // parse IP
126
+  if (!inet_pton(AF_INET6, strIp.c_str(), &iaIp))
127
+    return false;
128
+
129
+  // parse port
130
+  szPort = strPort.c_str();
131
+  iPort = strtoul(szPort, &szPortEnd, 10);
132
+  if (*szPort == 0 || *szPortEnd != 0)
133
+    return false;
134
+
135
+  m_addr.sin6_family = AF_INET6;
136
+  m_addr.sin6_port = htons(iPort);
137
+  m_addr.sin6_addr = iaIp;
138
+  return true;
139
+}
140
+
141
+/**
142
+ * @brief convert to string format
143
+ * @return string format
144
+ */
145
+std::string Udp6Addr::toStr() const
146
+{
147
+  std::stringstream strm;
148
+  char buf[INET6_ADDRSTRLEN];
149
+  strm << "["
150
+       << inet_ntop(AF_INET6, &m_addr.sin6_addr, buf, INET6_ADDRSTRLEN)
151
+       << "]:" << ntohs(m_addr.sin6_port);
152
+  return strm.str();
153
+}
154
+
155
+} // namespace Blinker
156
+
... ...
@@ -0,0 +1,70 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef UDP6ADDR_H
7
+#define UDP6ADDR_H
8
+
9
+#include <netinet/in.h>
10
+#include <string>
11
+#include <sys/socket.h>
12
+#include <sys/types.h>
13
+
14
+#include "Addr.h"
15
+
16
+namespace Blinker {
17
+
18
+/// UDP v6 address
19
+class Udp6Addr: public Addr
20
+{
21
+public:
22
+  /// constructor
23
+  Udp6Addr();
24
+
25
+  /// virtual destructor
26
+  virtual ~Udp6Addr();
27
+
28
+public:
29
+  /// comparison
30
+  //@{
31
+  int compare(const Udp6Addr &that) const;
32
+  bool operator==(const Udp6Addr &that) const;
33
+  bool operator!=(const Udp6Addr &that) const;
34
+  bool operator<(const Udp6Addr &that) const;
35
+  bool operator>(const Udp6Addr &that) const;
36
+  bool operator<=(const Udp6Addr &that) const;
37
+  bool operator>=(const Udp6Addr &that) const;
38
+  //@}
39
+
40
+  /// return address family
41
+  virtual int getFamily() const;
42
+
43
+  /// return port (use this function only if absolutely necessary)
44
+  virtual int getPort() const;
45
+
46
+  /// set port (use this function only if absolutely necessary)
47
+  virtual void setPort(int port);
48
+
49
+  /**
50
+   * @brief parse from string format
51
+   * @param[in] str string format
52
+   * @return if parsing was successful
53
+   */
54
+  virtual bool fromStr(const std::string &str);
55
+
56
+  /**
57
+   * @brief convert to string format
58
+   * @return string format
59
+   */
60
+  virtual std::string toStr() const;
61
+protected:
62
+  struct sockaddr_in6 m_addr;
63
+
64
+friend class Udp6Sock;
65
+}; // class Udp6Addr
66
+
67
+} // namespace Blinker
68
+
69
+#endif // #ifndef UDP6ADDR_H
70
+
... ...
@@ -0,0 +1,153 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include <fcntl.h>
7
+#include <netinet/in.h>
8
+#include <string>
9
+#include <sys/socket.h>
10
+#include <sys/types.h>
11
+#include <unistd.h>
12
+
13
+#include "Io.h"
14
+#include "Udp6Addr.h"
15
+#include "Udp6Sock.h"
16
+
17
+namespace Blinker {
18
+
19
+/// constructor
20
+Udp6Sock::Udp6Sock()
21
+{
22
+  int flags, opt;
23
+
24
+  // create socket
25
+  m_fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
26
+  if (m_fd == -1)
27
+    return;
28
+
29
+  // switch to nonblocking mode
30
+  flags = fcntl(m_fd, F_GETFL);
31
+  if (flags == -1 || fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) != 0) {
32
+    close(m_fd);
33
+    m_fd = -1;
34
+    return;
35
+  }
36
+
37
+  // enable address re-use
38
+  opt = 1;
39
+  if (setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) != 0) {
40
+    close(m_fd);
41
+    m_fd = -1;
42
+    return;
43
+  }
44
+}
45
+
46
+/// destructor
47
+Udp6Sock::~Udp6Sock()
48
+{
49
+  // exit if not initialized
50
+  if (m_fd == -1)
51
+    return;
52
+
53
+  // shutdown and close socket
54
+  shutdown(m_fd, SHUT_RDWR);
55
+  close(m_fd);
56
+  m_fd = -1;
57
+}
58
+
59
+/**
60
+ * @brief get address the socket is bound to
61
+ * @param[out] addr local addess the socket is bound to
62
+ * @return if local address could be obtained
63
+ */
64
+bool Udp6Sock::getAddr(Udp6Addr &addr)
65
+{
66
+  struct sockaddr * sockaddr;
67
+  socklen_t socklen;
68
+
69
+  // exit with error if not initialized
70
+  if (m_fd == -1)
71
+    return false;
72
+
73
+  // get local name of socket
74
+  sockaddr = (struct sockaddr *)&addr.m_addr;
75
+  socklen = sizeof(addr.m_addr);
76
+  if (getsockname(m_fd, sockaddr, &socklen) != 0)
77
+    return false;
78
+  return socklen <= sizeof(addr.m_addr); // check if not truncated
79
+}
80
+
81
+/**
82
+ * @brief bind socket
83
+ * @param[in] addr local address to bind to
84
+ * @return if binding succeeded
85
+ */
86
+bool Udp6Sock::bind(const Udp6Addr &addr)
87
+
88
+{
89
+  const struct sockaddr * sockaddr;
90
+  socklen_t socklen;
91
+
92
+  // exit with error if not initialized
93
+  if (m_fd == -1)
94
+    return false;
95
+
96
+  // bind
97
+  sockaddr = (const struct sockaddr *)&addr.m_addr;
98
+  socklen = sizeof(addr.m_addr);
99
+  return ::bind(m_fd, sockaddr, socklen) == 0;
100
+}
101
+
102
+/**
103
+ * @brief send to socket
104
+ * @param[in] data data to send in message
105
+ * @param[in] addr address the message should be sent to
106
+ * @return if the message could be sent
107
+ */
108
+bool Udp6Sock::send(const std::string &data, const Udp6Addr &addr)
109
+{
110
+  const struct sockaddr * sockaddr;
111
+  socklen_t socklen;
112
+  ssize_t len;
113
+
114
+  // exit with error if not initialized
115
+  if (m_fd == -1)
116
+    return false;
117
+
118
+  // send message
119
+  sockaddr = (const struct sockaddr *)&addr.m_addr;
120
+  socklen = sizeof(addr.m_addr);
121
+  len = sendto(m_fd, data.c_str(), data.size(), 0, sockaddr, socklen);
122
+  return len == (ssize_t)data.size();
123
+}
124
+
125
+/**
126
+ * @brief receive from socket
127
+ * @param[out] data data in received message
128
+ * @param[out] addr address the message has been received from
129
+ * @return if a message has been received
130
+ */
131
+bool Udp6Sock::recv(std::string &data, Udp6Addr &addr)
132
+{
133
+  char buf[65536];
134
+  struct sockaddr * sockaddr;
135
+  socklen_t socklen;
136
+  ssize_t len;
137
+
138
+  // exit with error if not initialized
139
+  if (m_fd == -1)
140
+    return false;
141
+
142
+  // receive message
143
+  sockaddr = (struct sockaddr *)&addr.m_addr;
144
+  socklen = sizeof(addr.m_addr);
145
+  len = recvfrom(m_fd, buf, sizeof(buf), 0, sockaddr, &socklen);
146
+  if (len < 0 || socklen > sizeof(addr.m_addr)) // error or address truncated
147
+    return false;
148
+  data.assign(buf, len);
149
+  return true;
150
+}
151
+
152
+} // namespace Blinker
153
+
... ...
@@ -0,0 +1,73 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef UDP6SOCK_H
7
+#define UDP6SOCK_H
8
+
9
+#include <string>
10
+
11
+#include "Io.h"
12
+#include "Udp6Addr.h"
13
+
14
+namespace Blinker {
15
+
16
+/**
17
+ * @brief UDP v6 socket
18
+ *
19
+ * UDP v6 socket in non-blocking mode with address re-usage enabled
20
+ */
21
+class Udp6Sock: public Io
22
+{
23
+public:
24
+  /// constructor
25
+  Udp6Sock();
26
+
27
+  /// destructor
28
+  ~Udp6Sock();
29
+
30
+private:
31
+  /// copy constructor disabled
32
+  Udp6Sock(const Udp6Sock &that);
33
+
34
+  /// assignment operator disabled
35
+  const Udp6Sock & operator=(const Udp6Sock &that);
36
+
37
+public:
38
+  /**
39
+   * @brief get address the socket is bound to
40
+   * @param[out] addr local addess the socket is bound to
41
+   * @return if local address could be obtained
42
+   */
43
+  bool getAddr(Udp6Addr &addr);
44
+
45
+  /**
46
+   * @brief bind socket
47
+   * @param[in] addr local address to bind to
48
+   * @return if binding succeeded
49
+   */
50
+  bool bind(const Udp6Addr &addr);
51
+
52
+  /**
53
+   * @brief send to socket
54
+   * @param[in] data data to send in message
55
+   * @param[in] addr address the message should be sent to
56
+   * @return if the message could be sent
57
+   */
58
+  bool send(const std::string &data, const Udp6Addr &addr);
59
+
60
+  /**
61
+   * @brief receive from socket
62
+   * @param[out] data data in received message
63
+   * @param[out] addr address the message has been received from
64
+   * @return if a message has been received
65
+   */
66
+  bool recv(std::string &data, Udp6Addr &addr);
67
+
68
+}; // class UdpSock
69
+
70
+} // namespace Blinker
71
+
72
+#endif // #ifndef UDP6SOCK_H
73
+
... ...
@@ -0,0 +1,21 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef UDP6PHONE_H
7
+#define UDP6PHONE_H
8
+
9
+#include "Phone_impl.h"
10
+#include "Udp6Addr.h"
11
+#include "Udp6Sock.h"
12
+
13
+namespace Blinker {
14
+
15
+/// UDP v6 phone connector
16
+typedef Phone<Udp6Addr, Udp6Sock> Udp6Phone;
17
+
18
+} // namespace Blinker
19
+
20
+#endif // #ifndef UDP6PHONE_H
21
+
... ...
@@ -0,0 +1,21 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef UDP6RECEIVER_H
7
+#define UDP6RECEIVER_H
8
+
9
+#include "Receiver_impl.h"
10
+#include "Udp6Addr.h"
11
+#include "Udp6Sock.h"
12
+
13
+namespace Blinker {
14
+
15
+/// UDP v6 stream sender
16
+typedef Receiver<Udp6Addr, Udp6Sock> Udp6Receiver;
17
+
18
+} // namespace Blinker
19
+
20
+#endif // #ifndef UDP6RECEIVER_H
21
+
... ...
@@ -0,0 +1,21 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef UDP6SENDER_H
7
+#define UDP6SENDER_H
8
+
9
+#include "Sender_impl.h"
10
+#include "Udp6Addr.h"
11
+#include "Udp6Sock.h"
12
+
13
+namespace Blinker {
14
+
15
+/// UDP v6 stream sender
16
+typedef Sender<Udp6Addr, Udp6Sock> Udp6Sender;
17
+
18
+} // namespace Blinker
19
+
20
+#endif // #ifndef UDP6SENDER_H
21
+
... ...
@@ -24,6 +24,9 @@
24 24
 #include "Udp4Phone.h"
25 25
 #include "Udp4Receiver.h"
26 26
 #include "Udp4Sender.h"
27
+#include "Udp6Phone.h"
28
+#include "Udp6Receiver.h"
29
+#include "Udp6Sender.h"
27 30
 
28 31
 using namespace Blinker;
29 32
 
... ...
@@ -50,6 +53,9 @@ void run(const std::string &dirConfig)
50 53
   MODULEMGR(Udp4Phone,    udp4phones);
51 54
   MODULEMGR(Udp4Receiver, udp4receivers);
52 55
   MODULEMGR(Udp4Sender,   udp4senders);
56
+  MODULEMGR(Udp6Phone,    udp6phones);
57
+  MODULEMGR(Udp6Receiver, udp6receivers);
58
+  MODULEMGR(Udp6Sender,   udp6senders);
53 59
 
54 60
 #undef MODULEMGR
55 61
 
56 62