Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / src / sockets / UdpSocket.cpp
blob5d949496b251aeabb589cc96dc1224bc7bbce658
1 /** \file UdpSocket.cpp
2 ** \date 2004-02-13
3 ** \author grymse@alhem.net
4 **/
5 /*
6 Copyright (C) 2004-2007 Anders Hedstrom
8 This library is made available under the terms of the GNU GPL.
10 If you would like to use this library in a closed-source application,
11 a separate license agreement is available. For information about
12 the closed-source license agreement for the C++ sockets library,
13 please visit http://www.alhem.net/Sockets/license.html and/or
14 email license@alhem.net.
16 This program is free software; you can redistribute it and/or
17 modify it under the terms of the GNU General Public License
18 as published by the Free Software Foundation; either version 2
19 of the License, or (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef _WIN32
31 #ifdef _MSC_VER
32 #pragma warning(disable:4786)
33 #endif
34 #include <stdlib.h>
35 #else
36 #include <errno.h>
37 #endif
39 #include "ISocketHandler.h"
40 #include "UdpSocket.h"
41 #include "Utility.h"
42 #include "Ipv4Address.h"
43 #include "Ipv6Address.h"
44 #ifdef ENABLE_EXCEPTIONS
45 #include "Exception.h"
46 #endif
47 // include this to see strange sights
48 //#include <linux/in6.h>
51 #ifdef SOCKETS_NAMESPACE
52 namespace SOCKETS_NAMESPACE {
53 #endif
56 UdpSocket::UdpSocket(ISocketHandler& h, int ibufsz, bool ipv6, int retries) : Socket(h)
57 , m_ibuf(new char[ibufsz])
58 , m_ibufsz(ibufsz)
59 , m_bind_ok(false)
60 , m_port(0)
61 , m_last_size_written(-1)
62 , m_retries(retries)
63 , m_b_read_ts(false)
65 #ifdef ENABLE_IPV6
66 #ifdef IPPROTO_IPV6
67 SetIpv6(ipv6);
68 #endif
69 #endif
73 UdpSocket::~UdpSocket()
75 Close();
76 delete[] m_ibuf;
80 int UdpSocket::Bind(port_t &port, int range)
82 #ifdef ENABLE_IPV6
83 #ifdef IPPROTO_IPV6
84 if (IsIpv6())
86 Ipv6Address ad(port);
87 return Bind(ad, range);
89 #endif
90 #endif
91 Ipv4Address ad(port);
92 return Bind(ad, range);
96 int UdpSocket::Bind(const std::string& intf, port_t &port, int range)
98 #ifdef ENABLE_IPV6
99 #ifdef IPPROTO_IPV6
100 if (IsIpv6())
102 Ipv6Address ad(intf, port);
103 if (ad.IsValid())
105 return Bind(ad, range);
107 SetCloseAndDelete();
108 return -1;
110 #endif
111 #endif
112 Ipv4Address ad(intf, port);
113 if (ad.IsValid())
115 return Bind(ad, range);
117 SetCloseAndDelete();
118 return -1;
122 int UdpSocket::Bind(ipaddr_t a, port_t &port, int range)
124 Ipv4Address ad(a, port);
125 return Bind(ad, range);
129 #ifdef ENABLE_IPV6
130 #ifdef IPPROTO_IPV6
131 int UdpSocket::Bind(in6_addr a, port_t &port, int range)
133 Ipv6Address ad(a, port);
134 return Bind(ad, range);
136 #endif
137 #endif
140 int UdpSocket::Bind(SocketAddress& ad, int range)
142 if (GetSocket() == INVALID_SOCKET)
144 Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
146 if (GetSocket() != INVALID_SOCKET)
148 SetNonblocking(true);
149 int n = bind(GetSocket(), ad, ad);
150 int tries = range;
151 while (n == -1 && tries--)
153 ad.SetPort(ad.GetPort() + 1);
154 n = bind(GetSocket(), ad, ad);
156 if (n == -1)
158 Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL);
159 SetCloseAndDelete();
160 #ifdef ENABLE_EXCEPTIONS
161 throw Exception("bind() failed for UdpSocket, port:range: " + Utility::l2string(ad.GetPort()) + ":" + Utility::l2string(range));
162 #endif
163 return -1;
165 m_bind_ok = true;
166 m_port = ad.GetPort();
167 return 0;
169 return -1;
173 /** if you wish to use Send, first Open a connection */
174 bool UdpSocket::Open(ipaddr_t l, port_t port)
176 Ipv4Address ad(l, port);
177 return Open(ad);
181 bool UdpSocket::Open(const std::string& host, port_t port)
183 #ifdef ENABLE_IPV6
184 #ifdef IPPROTO_IPV6
185 if (IsIpv6())
187 Ipv6Address ad(host, port);
188 if (ad.IsValid())
190 return Open(ad);
192 return false;
194 #endif
195 #endif
196 Ipv4Address ad(host, port);
197 if (ad.IsValid())
199 return Open(ad);
201 return false;
205 #ifdef ENABLE_IPV6
206 #ifdef IPPROTO_IPV6
207 bool UdpSocket::Open(struct in6_addr& a, port_t port)
209 Ipv6Address ad(a, port);
210 return Open(ad);
212 #endif
213 #endif
216 bool UdpSocket::Open(SocketAddress& ad)
218 if (GetSocket() == INVALID_SOCKET)
220 Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
222 if (GetSocket() != INVALID_SOCKET)
224 SetNonblocking(true);
225 if (connect(GetSocket(), ad, ad) == -1)
227 Handler().LogError(this, "connect", Errno, StrError(Errno), LOG_LEVEL_FATAL);
228 SetCloseAndDelete();
229 return false;
231 SetConnected();
232 return true;
234 return false;
238 void UdpSocket::CreateConnection()
240 #ifdef ENABLE_IPV6
241 #ifdef IPPROTO_IPV6
242 if (IsIpv6())
244 if (GetSocket() == INVALID_SOCKET)
246 SOCKET s = CreateSocket(AF_INET6, SOCK_DGRAM, "udp");
247 if (s == INVALID_SOCKET)
249 return;
251 SetNonblocking(true, s);
252 Attach(s);
254 return;
256 #endif
257 #endif
258 if (GetSocket() == INVALID_SOCKET)
260 SOCKET s = CreateSocket(AF_INET, SOCK_DGRAM, "udp");
261 if (s == INVALID_SOCKET)
263 return;
265 SetNonblocking(true, s);
266 Attach(s);
271 /** send to specified address */
272 void UdpSocket::SendToBuf(const std::string& h, port_t p, const char *data, int len, int flags)
274 #ifdef ENABLE_IPV6
275 #ifdef IPPROTO_IPV6
276 if (IsIpv6())
278 Ipv6Address ad(h, p);
279 if (ad.IsValid())
281 SendToBuf(ad, data, len, flags);
283 return;
285 #endif
286 #endif
287 Ipv4Address ad(h, p);
288 if (ad.IsValid())
290 SendToBuf(ad, data, len, flags);
295 /** send to specified address */
296 void UdpSocket::SendToBuf(ipaddr_t a, port_t p, const char *data, int len, int flags)
298 Ipv4Address ad(a, p);
299 SendToBuf(ad, data, len, flags);
303 #ifdef ENABLE_IPV6
304 #ifdef IPPROTO_IPV6
305 void UdpSocket::SendToBuf(in6_addr a, port_t p, const char *data, int len, int flags)
307 Ipv6Address ad(a, p);
308 SendToBuf(ad, data, len, flags);
310 #endif
311 #endif
314 void UdpSocket::SendToBuf(SocketAddress& ad, const char *data, int len, int flags)
316 if (GetSocket() == INVALID_SOCKET)
318 Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
320 if (GetSocket() != INVALID_SOCKET)
322 SetNonblocking(true);
323 if ((m_last_size_written = sendto(GetSocket(), data, len, flags, ad, ad)) == -1)
325 Handler().LogError(this, "sendto", Errno, StrError(Errno), LOG_LEVEL_ERROR);
331 void UdpSocket::SendTo(const std::string& a, port_t p, const std::string& str, int flags)
333 SendToBuf(a, p, str.c_str(), (int)str.size(), flags);
337 void UdpSocket::SendTo(ipaddr_t a, port_t p, const std::string& str, int flags)
339 SendToBuf(a, p, str.c_str(), (int)str.size(), flags);
343 #ifdef ENABLE_IPV6
344 #ifdef IPPROTO_IPV6
345 void UdpSocket::SendTo(in6_addr a, port_t p, const std::string& str, int flags)
347 SendToBuf(a, p, str.c_str(), (int)str.size(), flags);
349 #endif
350 #endif
353 void UdpSocket::SendTo(SocketAddress& ad, const std::string& str, int flags)
355 SendToBuf(ad, str.c_str(), (int)str.size(), flags);
359 /** send to connected address */
360 void UdpSocket::SendBuf(const char *data, size_t len, int flags)
362 if (!IsConnected())
364 Handler().LogError(this, "SendBuf", 0, "not connected", LOG_LEVEL_ERROR);
365 return;
367 if ((m_last_size_written = send(GetSocket(), data, (int)len, flags)) == -1)
369 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_ERROR);
374 void UdpSocket::Send(const std::string& str, int flags)
376 SendBuf(str.c_str(), (int)str.size(), flags);
380 #if defined(LINUX) || defined(MACOSX)
381 int UdpSocket::ReadTS(char *ioBuf, int inBufSize, struct sockaddr *from, socklen_t fromlen, struct timeval *ts)
383 struct msghdr msg;
384 struct iovec vec[1];
385 union {
386 struct cmsghdr cm;
387 #ifdef MACOSX
388 #ifdef __DARWIN_UNIX03
389 #define ALIGNBYTES __DARWIN_ALIGNBYTES
390 #endif
391 #define myALIGN(p) (((unsigned int)(p) + ALIGNBYTES) &~ ALIGNBYTES)
392 #define myCMSG_SPACE(l) (myALIGN(sizeof(struct cmsghdr)) + myALIGN(l))
393 char data[ myCMSG_SPACE(sizeof(struct timeval)) ];
394 #else
395 char data[ CMSG_SPACE(sizeof(struct timeval)) ];
396 #endif
397 } cmsg_un;
398 struct cmsghdr *cmsg;
399 struct timeval *tv;
401 vec[0].iov_base = ioBuf;
402 vec[0].iov_len = inBufSize;
404 memset(&msg, 0, sizeof(msg));
405 memset(from, 0, fromlen);
406 memset(ioBuf, 0, inBufSize);
407 memset(&cmsg_un, 0, sizeof(cmsg_un));
409 msg.msg_name = (caddr_t)from;
410 msg.msg_namelen = fromlen;
411 msg.msg_iov = vec;
412 msg.msg_iovlen = 1;
413 msg.msg_control = cmsg_un.data;
414 msg.msg_controllen = sizeof(cmsg_un.data);
415 msg.msg_flags = 0;
417 // Original version - for reference only
418 //int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
420 int n = recvmsg(GetSocket(), &msg, MSG_DONTWAIT);
422 // now ioBuf will contain the data, as if we used recvfrom
424 // Now get the time
425 if(n != -1 && msg.msg_controllen >= sizeof(struct cmsghdr) && !(msg.msg_flags & MSG_CTRUNC))
427 tv = 0;
428 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
430 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP)
432 tv = (struct timeval *)CMSG_DATA(cmsg);
435 if (tv)
437 memcpy(ts, tv, sizeof(struct timeval));
440 // The address is in network order, but that's OK right now
441 return n;
443 #endif
446 void UdpSocket::OnRead()
448 #ifdef ENABLE_IPV6
449 #ifdef IPPROTO_IPV6
450 if (IsIpv6())
452 struct sockaddr_in6 sa;
453 socklen_t sa_len = sizeof(sa);
454 if (m_b_read_ts)
456 struct timeval ts;
457 Utility::GetTime(&ts);
458 #if !defined(LINUX) && !defined(MACOSX)
459 int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
460 #else
461 int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts);
462 #endif
463 if (n > 0)
465 this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts);
467 else
468 if (n == -1)
470 #ifdef _WIN32
471 if (Errno != WSAEWOULDBLOCK)
472 #else
473 if (Errno != EWOULDBLOCK)
474 #endif
475 Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
477 return;
479 int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
480 int q = m_retries; // receive max 10 at one cycle
481 while (n > 0)
483 if (sa_len != sizeof(sa))
485 Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING);
487 this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len);
488 if (!q--)
489 break;
491 n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
493 if (n == -1)
495 #ifdef _WIN32
496 if (Errno != WSAEWOULDBLOCK)
497 #else
498 if (Errno != EWOULDBLOCK)
499 #endif
500 Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
502 return;
504 #endif
505 #endif
506 struct sockaddr_in sa;
507 socklen_t sa_len = sizeof(sa);
508 if (m_b_read_ts)
510 struct timeval ts;
511 Utility::GetTime(&ts);
512 #if !defined(LINUX) && !defined(MACOSX)
513 int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
514 #else
515 int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts);
516 #endif
517 if (n > 0)
519 this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts);
521 else
522 if (n == -1)
524 #ifdef _WIN32
525 if (Errno != WSAEWOULDBLOCK)
526 #else
527 if (Errno != EWOULDBLOCK)
528 #endif
529 Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
531 return;
533 int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
534 int q = m_retries;
535 while (n > 0)
537 if (sa_len != sizeof(sa))
539 Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING);
541 this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len);
542 if (!q--)
543 break;
545 n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
547 if (n == -1)
549 #ifdef _WIN32
550 if (Errno != WSAEWOULDBLOCK)
551 #else
552 if (Errno != EWOULDBLOCK)
553 #endif
554 Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
559 void UdpSocket::SetBroadcast(bool b)
561 int one = 1;
562 int zero = 0;
564 if (GetSocket() == INVALID_SOCKET)
566 CreateConnection();
568 if (b)
570 if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof(one)) == -1)
572 Handler().LogError(this, "SetBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING);
575 else
577 if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *) &zero, sizeof(zero)) == -1)
579 Handler().LogError(this, "SetBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING);
585 bool UdpSocket::IsBroadcast()
587 int is_broadcast = 0;
588 socklen_t size;
590 if (GetSocket() == INVALID_SOCKET)
592 CreateConnection();
594 if (getsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *)&is_broadcast, &size) == -1)
596 Handler().LogError(this, "IsBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING);
598 return is_broadcast != 0;
602 void UdpSocket::SetMulticastTTL(int ttl)
604 if (GetSocket() == INVALID_SOCKET)
606 CreateConnection();
608 if (setsockopt(GetSocket(), SOL_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(int)) == -1)
610 Handler().LogError(this, "SetMulticastTTL", Errno, StrError(Errno), LOG_LEVEL_WARNING);
615 int UdpSocket::GetMulticastTTL()
617 int ttl = 0;
618 socklen_t size = sizeof(int);
620 if (GetSocket() == INVALID_SOCKET)
622 CreateConnection();
624 if (getsockopt(GetSocket(), SOL_IP, IP_MULTICAST_TTL, (char *)&ttl, &size) == -1)
626 Handler().LogError(this, "GetMulticastTTL", Errno, StrError(Errno), LOG_LEVEL_WARNING);
628 return ttl;
632 void UdpSocket::SetMulticastLoop(bool x)
634 if (GetSocket() == INVALID_SOCKET)
636 CreateConnection();
638 #ifdef ENABLE_IPV6
639 #ifdef IPPROTO_IPV6
640 if (IsIpv6())
642 int val = x ? 1 : 0;
643 if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1)
645 Handler().LogError(this, "SetMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
647 return;
649 #endif
650 #endif
651 int val = x ? 1 : 0;
652 if (setsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1)
654 Handler().LogError(this, "SetMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
659 bool UdpSocket::IsMulticastLoop()
661 if (GetSocket() == INVALID_SOCKET)
663 CreateConnection();
665 #ifdef ENABLE_IPV6
666 #ifdef IPPROTO_IPV6
667 if (IsIpv6())
669 int is_loop = 0;
670 socklen_t size = sizeof(int);
671 if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&is_loop, &size) == -1)
673 Handler().LogError(this, "IsMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
675 return is_loop ? true : false;
677 #endif
678 #endif
679 int is_loop = 0;
680 socklen_t size = sizeof(int);
681 if (getsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&is_loop, &size) == -1)
683 Handler().LogError(this, "IsMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
685 return is_loop ? true : false;
689 void UdpSocket::AddMulticastMembership(const std::string& group, const std::string& local_if, int if_index)
691 if (GetSocket() == INVALID_SOCKET)
693 CreateConnection();
695 #ifdef ENABLE_IPV6
696 #ifdef IPPROTO_IPV6
697 if (IsIpv6())
699 struct ipv6_mreq x;
700 struct in6_addr addr;
701 if (Utility::u2ip( group, addr ))
703 x.ipv6mr_multiaddr = addr;
704 x.ipv6mr_interface = if_index;
705 if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&x, sizeof(struct ipv6_mreq)) == -1)
707 Handler().LogError(this, "AddMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
710 return;
712 #endif
713 #endif
714 struct ip_mreq x; // ip_mreqn
715 ipaddr_t addr;
716 if (Utility::u2ip( group, addr ))
718 memcpy(&x.imr_multiaddr.s_addr, &addr, sizeof(addr));
719 Utility::u2ip( local_if, addr);
720 memcpy(&x.imr_interface.s_addr, &addr, sizeof(addr));
721 // x.imr_ifindex = if_index;
722 if (setsockopt(GetSocket(), SOL_IP, IP_ADD_MEMBERSHIP, (char *)&x, sizeof(struct ip_mreq)) == -1)
724 Handler().LogError(this, "AddMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
730 void UdpSocket::DropMulticastMembership(const std::string& group, const std::string& local_if, int if_index)
732 if (GetSocket() == INVALID_SOCKET)
734 CreateConnection();
736 #ifdef ENABLE_IPV6
737 #ifdef IPPROTO_IPV6
738 if (IsIpv6())
740 struct ipv6_mreq x;
741 struct in6_addr addr;
742 if (Utility::u2ip( group, addr ))
744 x.ipv6mr_multiaddr = addr;
745 x.ipv6mr_interface = if_index;
746 if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ipv6_mreq)) == -1)
748 Handler().LogError(this, "DropMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
751 return;
753 #endif
754 #endif
755 struct ip_mreq x; // ip_mreqn
756 ipaddr_t addr;
757 if (Utility::u2ip( group, addr ))
759 memcpy(&x.imr_multiaddr.s_addr, &addr, sizeof(addr));
760 Utility::u2ip( local_if, addr);
761 memcpy(&x.imr_interface.s_addr, &addr, sizeof(addr));
762 // x.imr_ifindex = if_index;
763 if (setsockopt(GetSocket(), SOL_IP, IP_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ip_mreq)) == -1)
765 Handler().LogError(this, "DropMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
771 #ifdef ENABLE_IPV6
772 #ifdef IPPROTO_IPV6
773 void UdpSocket::SetMulticastHops(int hops)
775 if (GetSocket() == INVALID_SOCKET)
777 CreateConnection();
779 if (!IsIpv6())
781 Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR);
782 return;
784 if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, sizeof(int)) == -1)
786 Handler().LogError(this, "SetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING);
791 int UdpSocket::GetMulticastHops()
793 if (GetSocket() == INVALID_SOCKET)
795 CreateConnection();
797 if (!IsIpv6())
799 Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR);
800 return -1;
802 int hops = 0;
803 socklen_t size = sizeof(int);
804 if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, &size) == -1)
806 Handler().LogError(this, "GetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING);
808 return hops;
810 #endif // IPPROTO_IPV6
811 #endif
814 bool UdpSocket::IsBound()
816 return m_bind_ok;
820 void UdpSocket::OnRawData(const char *buf, size_t len, struct sockaddr *sa, socklen_t sa_len)
825 void UdpSocket::OnRawData(const char *buf, size_t len, struct sockaddr *sa, socklen_t sa_len, struct timeval *ts)
830 port_t UdpSocket::GetPort()
832 return m_port;
836 int UdpSocket::GetLastSizeWritten()
838 return m_last_size_written;
842 void UdpSocket::SetTimestamp(bool x)
844 m_b_read_ts = x;
848 #ifdef SOCKETS_NAMESPACE
850 #endif