30 #define EADDRINUSE WSAEADDRINUSE
37 const ibrcommon::vaddress UDPDatagramService::BROADCAST_ADDR(
"ff02::1", UDPDatagramService::BROADCAST_PORT, AF_INET6);
40 : _msock(NULL), _iface(iface), _bind_port(port)
71 _msock->
join(BROADCAST_ADDR, _iface);
73 if (e.
error() != EADDRINUSE) {
88 std::list<ibrcommon::vaddress> addrs = _iface.
getAddresses();
91 std::stringstream ss; ss << _bind_port;
93 for (std::list<ibrcommon::vaddress>::iterator iter = addrs.begin(); iter != addrs.end(); ++iter) {
109 throw DatagramException(
"bind failed");
135 UDPDatagramService::decode(identifier, destination);
138 send(type, flags, seqno, destination, buf, length);
149 send(type, flags, seqno, BROADCAST_ADDR, buf, length);
155 std::vector<char> tmp(length + 2);
161 tmp[1] =
static_cast<char>((0xf0 & (flags << 4)) | (0x0f & seqno));
164 ::memcpy(&tmp[2], buf, length);
166 IBRCOMMON_LOGGER_DEBUG_TAG(
"UDPDatagramService", 20) <<
"send() type: " << std::hex << (int)type <<
"; flags: " << std::hex << (
int)flags << "; seqno: " << std::dec << seqno << "; address: " << destination.toString() <<
IBRCOMMON_LOGGER_ENDL;
169 ibrcommon::
socketset sockset = _vsocket.getAll();
170 for (ibrcommon::
socketset::iterator iter = sockset.begin(); iter != sockset.end(); ++iter) {
171 if ((*iter) == _msock)
continue;
174 sock.
sendto(&tmp[0], length + 2, 0, destination);
177 }
catch (
const std::bad_cast&) { }
181 throw DatagramException(
"send failed");
183 throw DatagramException(
"send failed");
199 _vsocket.select(&readfds, NULL, NULL, NULL);
201 for (ibrcommon::socketset::iterator iter = readfds.begin(); iter != readfds.end(); ++iter) {
205 std::vector<char> tmp(length + 2);
207 size_t ret = sock.
recvfrom(&tmp[0], length + 2, 0, peeraddr);
213 flags = 0x0f & (tmp[1] >> 4);
214 seqno = 0x0f & tmp[1];
217 address = UDPDatagramService::encode(peeraddr);
220 ::memcpy(buf, &tmp[2], ret - 2);
225 }
catch (
const std::bad_cast&) {
244 std::list<ibrcommon::vaddress> addrs = _iface.
getAddresses();
246 for (std::list<ibrcommon::vaddress>::iterator iter = addrs.begin(); iter != addrs.end(); ++iter) {
254 return UDPDatagramService::encode(addr, _bind_port);
291 const std::string UDPDatagramService::encode(
const ibrcommon::vaddress &address,
const int port)
293 std::stringstream ss;
294 ss <<
"ip=" << address.
address() <<
";port=";
296 if (port == 0) ss << address.
service();
303 void UDPDatagramService::decode(
const std::string &identifier,
ibrcommon::vaddress &address)
310 std::vector<string>::const_iterator param_iter = parameters.begin();
312 while (param_iter != parameters.end())
316 if (p[0].compare(
"ip") == 0)
321 if (p[0].compare(
"port") == 0)