libzmq  master
ZeroMQ C++ Core Engine (LIBZMQ)
udp_address.cpp
Go to the documentation of this file.
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 
51  : is_mutlicast(false)
52 {
53  memset (&bind_address, 0, sizeof bind_address);
54  memset (&dest_address, 0, sizeof dest_address);
55 }
56 
58 {
59 }
60 
61 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  const char *delimiter = strrchr (name_, ':');
65  if (!delimiter) {
66  errno = EINVAL;
67  return -1;
68  }
69 
70  // Separate the address/port.
71  std::string addr_str (name_, delimiter - name_);
72  std::string port_str (delimiter + 1);
73 
74  // Parse the port number (0 is not a valid port).
75  uint16_t port = (uint16_t) atoi (port_str.c_str ());
76  if (port == 0) {
77  errno = EINVAL;
78  return -1;
79  }
80 
81  dest_address.sin_family = AF_INET;
82  dest_address.sin_port = htons (port);
83 
84  // Only when the udp is receiver we allow * as the address
85  if (addr_str == "*" && receiver_)
86  dest_address.sin_addr.s_addr = htons (INADDR_ANY);
87  else
88  dest_address.sin_addr.s_addr = inet_addr (addr_str.c_str ());
89 
90  if (dest_address.sin_addr.s_addr == INADDR_NONE) {
91  errno = EINVAL;
92  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  int i = dest_address.sin_addr.s_addr & 0xFF;
99  if(i >= 224 && i <= 239) {
100  multicast = dest_address.sin_addr;
101  is_mutlicast = true;
102  }
103  else
104  is_mutlicast = false;
105 
106  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  if (receiver_ && !is_mutlicast)
116  else {
117  bind_address.sin_family = AF_INET;
118  bind_address.sin_port = htons (port);
119  bind_address.sin_addr.s_addr = htons (INADDR_ANY);
120  }
121 
122  address = name_;
123 
124  return 0;
125 }
126 
127 int zmq::udp_address_t::to_string (std::string &addr_)
128 {
129  addr_ = address;
130  return 0;
131 }
132 
134 {
135  return is_mutlicast;
136 }
137 
138 const sockaddr* zmq::udp_address_t::bind_addr () const
139 {
140  return (sockaddr *) &bind_address;
141 }
142 
144 {
145  return sizeof (sockaddr_in);
146 }
147 
148 const sockaddr* zmq::udp_address_t::dest_addr () const
149 {
150  return (sockaddr *) &dest_address;
151 }
152 
154 {
155  return sizeof (sockaddr_in);
156 }
157 
158 const in_addr zmq::udp_address_t::multicast_ip () const
159 {
160  return multicast;
161 }
162 
163 const in_addr zmq::udp_address_t::interface_ip () const
164 {
165  return iface;
166 }
167 
168 #if defined ZMQ_HAVE_WINDOWS
169 unsigned short zmq::udp_address_t::family () const
170 #else
171 sa_family_t zmq::udp_address_t::family () const
172 #endif
173 {
174  return AF_INET;
175 }
sockaddr_in dest_address
Definition: udp_address.hpp:76
sa_family_t family() const
socklen_t bind_addrlen() const
virtual int to_string(std::string &addr_)
const sockaddr * bind_addr() const
std::string address
Definition: udp_address.hpp:78
sockaddr_in bind_address
Definition: udp_address.hpp:75
const sockaddr * dest_addr() const
virtual ~udp_address_t()
Definition: udp_address.cpp:57
int resolve(const char *name_, bool receiver_)
Definition: udp_address.cpp:61
const in_addr multicast_ip() const
socklen_t dest_addrlen() const
const in_addr interface_ip() const
bool is_mcast() const