Line data Source code
1 : /*
2 : Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3 :
4 : This file is part of libzmq, the ZeroMQ core engine in C++.
5 :
6 : libzmq is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU Lesser General Public License (LGPL) as published
8 : by the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : As a special exception, the Contributors give you permission to link
12 : this library with independent modules to produce an executable,
13 : regardless of the license terms of these independent modules, and to
14 : copy and distribute the resulting executable under terms of your choice,
15 : provided that you also meet, for each linked independent module, the
16 : terms and conditions of the license of that module. An independent
17 : module is a module which is not derived from or based on this library.
18 : If you modify this library, you must extend this exception to your
19 : version of the library.
20 :
21 : libzmq is distributed in the hope that it will be useful, but WITHOUT
22 : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 : License for more details.
25 :
26 : You should have received a copy of the GNU Lesser General Public License
27 : along with this program. If not, see <http://www.gnu.org/licenses/>.
28 : */
29 :
30 : #include "precompiled.hpp"
31 : #include <string>
32 : #include <sstream>
33 :
34 : #include "macros.hpp"
35 : #include "udp_address.hpp"
36 : #include "platform.hpp"
37 : #include "stdint.hpp"
38 : #include "err.hpp"
39 : #include "ip.hpp"
40 :
41 : #ifdef ZMQ_HAVE_WINDOWS
42 : #include "windows.hpp"
43 : #else
44 : #include <sys/types.h>
45 : #include <arpa/inet.h>
46 : #include <netdb.h>
47 : #include <ctype.h>
48 : #endif
49 :
50 6 : zmq::udp_address_t::udp_address_t ()
51 6 : : is_mutlicast(false)
52 : {
53 6 : memset (&bind_address, 0, sizeof bind_address);
54 6 : memset (&dest_address, 0, sizeof dest_address);
55 6 : }
56 :
57 6 : zmq::udp_address_t::~udp_address_t ()
58 : {
59 6 : }
60 :
61 6 : int zmq::udp_address_t::resolve (const char *name_, bool receiver_)
62 : {
63 : // Find the ':' at end that separates address from the port number.
64 6 : const char *delimiter = strrchr (name_, ':');
65 6 : if (!delimiter) {
66 0 : errno = EINVAL;
67 0 : return -1;
68 : }
69 :
70 : // Separate the address/port.
71 6 : std::string addr_str (name_, delimiter - name_);
72 6 : std::string port_str (delimiter + 1);
73 :
74 : // Parse the port number (0 is not a valid port).
75 12 : uint16_t port = (uint16_t) atoi (port_str.c_str ());
76 6 : if (port == 0) {
77 0 : errno = EINVAL;
78 0 : return -1;
79 : }
80 :
81 6 : dest_address.sin_family = AF_INET;
82 6 : dest_address.sin_port = htons (port);
83 :
84 : // Only when the udp is receiver we allow * as the address
85 6 : if (addr_str == "*" && receiver_)
86 3 : dest_address.sin_addr.s_addr = htons (INADDR_ANY);
87 : else
88 3 : dest_address.sin_addr.s_addr = inet_addr (addr_str.c_str ());
89 :
90 6 : if (dest_address.sin_addr.s_addr == INADDR_NONE) {
91 0 : errno = EINVAL;
92 0 : return -1;
93 : }
94 :
95 : // we will check only first byte of IP
96 : // and if it from 224 to 239, then it can
97 : // represent multicast IP.
98 6 : int i = dest_address.sin_addr.s_addr & 0xFF;
99 6 : if(i >= 224 && i <= 239) {
100 0 : multicast = dest_address.sin_addr;
101 0 : is_mutlicast = true;
102 : }
103 : else
104 6 : is_mutlicast = false;
105 :
106 6 : iface.s_addr = htons (INADDR_ANY);
107 : if (iface.s_addr == INADDR_NONE) {
108 : errno = EINVAL;
109 : return -1;
110 : }
111 :
112 : // If a receiver and not a multicast, the dest address
113 : // is actually the bind address
114 6 : if (receiver_ && !is_mutlicast)
115 3 : bind_address = dest_address;
116 : else {
117 3 : bind_address.sin_family = AF_INET;
118 3 : bind_address.sin_port = htons (port);
119 3 : bind_address.sin_addr.s_addr = htons (INADDR_ANY);
120 : }
121 :
122 6 : address = name_;
123 :
124 : return 0;
125 : }
126 :
127 6 : int zmq::udp_address_t::to_string (std::string &addr_)
128 : {
129 6 : addr_ = address;
130 6 : return 0;
131 : }
132 :
133 3 : bool zmq::udp_address_t::is_mcast () const
134 : {
135 3 : return is_mutlicast;
136 : }
137 :
138 3 : const sockaddr* zmq::udp_address_t::bind_addr () const
139 : {
140 3 : return (sockaddr *) &bind_address;
141 : }
142 :
143 3 : socklen_t zmq::udp_address_t::bind_addrlen () const
144 : {
145 3 : return sizeof (sockaddr_in);
146 : }
147 :
148 3 : const sockaddr* zmq::udp_address_t::dest_addr () const
149 : {
150 3 : return (sockaddr *) &dest_address;
151 : }
152 :
153 3 : socklen_t zmq::udp_address_t::dest_addrlen () const
154 : {
155 3 : return sizeof (sockaddr_in);
156 : }
157 :
158 0 : const in_addr zmq::udp_address_t::multicast_ip () const
159 : {
160 0 : return multicast;
161 : }
162 :
163 0 : const in_addr zmq::udp_address_t::interface_ip () const
164 : {
165 0 : return iface;
166 : }
167 :
168 : #if defined ZMQ_HAVE_WINDOWS
169 : unsigned short zmq::udp_address_t::family () const
170 : #else
171 6 : sa_family_t zmq::udp_address_t::family () const
172 : #endif
173 : {
174 6 : return AF_INET;
175 : }
|