OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4NetIOSimpleUDP Class Referenceabstract

#include <C4NetIO.h>

Inheritance diagram for C4NetIOSimpleUDP:
[legend]
Collaboration diagram for C4NetIOSimpleUDP:
[legend]

Public Types

typedef EndpointAddress addr_t
 

Public Member Functions

 C4NetIOSimpleUDP ()
 
virtual ~C4NetIOSimpleUDP ()
 
virtual bool Init (uint16_t iPort=addr_t::IPPORT_NONE)
 
virtual bool InitBroadcast (addr_t *pBroadcastAddr)
 
virtual bool Close ()
 
virtual bool CloseBroadcast ()
 
virtual bool Execute (int iMaxTime=TO_INF, pollfd *=0)
 
virtual bool Send (const C4NetIOPacket &rPacket)
 
virtual bool Broadcast (const C4NetIOPacket &rPacket)
 
virtual void UnBlock ()
 
virtual void GetFDs (std::vector< struct pollfd > &FDs)
 
virtual bool Connect (const addr_t &addr)
 
virtual bool Close (const addr_t &addr)
 
virtual bool SetBroadcast (const addr_t &addr, bool fSet=true)
 
virtual bool GetStatistic (int *pBroadcastRate)
 
virtual bool GetConnStatistic (const addr_t &addr, int *pIRate, int *pORate, int *pLoss)
 
virtual void ClearStatistic ()
 
virtual void SetCallback (CBClass *pnCallback)
 
virtual bool IsNotify ()
 
virtual bool Send (const class C4NetIOPacket &rPacket)=0
 
virtual bool Broadcast (const class C4NetIOPacket &rPacket)=0
 
virtual const char * GetError () const
 
void ResetError ()
 
virtual void SetCallback (CBClass *pnCallback)=0
 
bool ExecuteUntil (int iTimeout=-1)
 
virtual C4TimeMilliseconds GetNextTick (C4TimeMilliseconds tNow)
 
bool IsSignaled ()
 
virtual bool IsLowPriority ()
 
virtual uint32_t TimerInterval ()
 

Static Public Member Functions

static std::vector< HostAddressGetLocalAddresses ()
 

Static Public Attributes

static const int TO_INF = -1
 

Protected Member Functions

const addr_tgetMCAddr () const
 
bool SetMCLoopback (int fLoopback)
 
bool getMCLoopback () const
 
void SetReUseAddress (bool fAllow)
 
bool InitIPv6Socket (SOCKET socket)
 
void SetError (const char *strnError, bool fSockErr=false)
 
void Changed ()
 

Protected Attributes

StdCopyStrBuf Error
 

Detailed Description

Definition at line 497 of file C4NetIO.h.

Member Typedef Documentation

typedef EndpointAddress C4NetIO::addr_t
inherited

Definition at line 212 of file C4NetIO.h.

Constructor & Destructor Documentation

C4NetIOSimpleUDP::C4NetIOSimpleUDP ( )

Definition at line 1843 of file C4NetIO.cpp.

1844  : fInit(false), fMultiCast(false), iPort(~0), sock(INVALID_SOCKET),
1845 #ifdef STDSCHEDULER_USE_EVENTS
1846  hEvent(nullptr),
1847 #endif
1848  fAllowReUse(false)
1849 {
1850 
1851 }
#define INVALID_SOCKET
Definition: C4NetIO.h:37
C4NetIOSimpleUDP::~C4NetIOSimpleUDP ( )
virtual

Definition at line 1853 of file C4NetIO.cpp.

References Close().

1854 {
1855  Close();
1856 }
virtual bool Close()
Definition: C4NetIO.cpp:2001

Here is the call graph for this function:

Member Function Documentation

virtual bool C4NetIO::Broadcast ( const class C4NetIOPacket rPacket)
pure virtualinherited
bool C4NetIOSimpleUDP::Broadcast ( const C4NetIOPacket rPacket)
virtual

Reimplemented in C4NetIOUDP.

Definition at line 2160 of file C4NetIO.cpp.

References C4NetIOPacket::getRef(), and Send().

Referenced by C4NetIOUDP::DoLoopbackTest(), and C4NetIOUDP::InitBroadcast().

2161 {
2162  // just set broadcast address and send
2163  return C4NetIOSimpleUDP::Send(C4NetIOPacket(rPacket.getRef(), MCAddr));
2164 }
C4NetIOPacket getRef() const
Definition: C4NetIO.h:324
virtual bool Send(const C4NetIOPacket &rPacket)
Definition: C4NetIO.cpp:2140

Here is the call graph for this function:

Here is the caller graph for this function:

void StdSchedulerProc::Changed ( )
protectedinherited

Definition at line 121 of file StdScheduler.cpp.

References s.

Referenced by C4NetIOTCP::Accept(), C4NetIOTCP::AddConnectWait(), C4NetIOUDP::AddPeer(), C4NetIOTCP::Listen(), and CStdTimerProc::SetDelay().

122 {
123  auto s = scheduler;
124  if (s)
125  s->Changed(this);
126 }
#define s

Here is the caller graph for this function:

virtual void C4NetIOSimpleUDP::ClearStatistic ( )
inlinevirtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 529 of file C4NetIO.h.

529 { assert(false); }
bool C4NetIOSimpleUDP::Close ( )
virtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 2001 of file C4NetIO.cpp.

References CloseBroadcast(), closesocket, INVALID_SOCKET, and C4NetIO::ResetError().

Referenced by C4NetIOUDP::Close(), Init(), ~C4NetIOSimpleUDP(), and C4StartupNetDlg::~C4StartupNetDlg().

2002 {
2003  // should be initialized
2004  if (!fInit) return true;
2005 
2006  ResetError();
2007 
2008  // deactivate multicast
2009  if (fMultiCast)
2010  CloseBroadcast();
2011 
2012  // close sockets
2013  if (sock != INVALID_SOCKET)
2014  {
2015  closesocket(sock);
2016  sock = INVALID_SOCKET;
2017  }
2018 
2019 #ifdef STDSCHEDULER_USE_EVENTS
2020  // close event
2021  if (hEvent != nullptr)
2022  {
2023  WSACloseEvent(hEvent);
2024  hEvent = nullptr;
2025  }
2026 #else
2027  // close pipes
2028  close(Pipe[0]);
2029  close(Pipe[1]);
2030 #endif
2031 
2032 #ifdef HAVE_WINSOCK
2033  // release winsock
2034  ReleaseWinSock();
2035 #endif
2036 
2037  // ok
2038  fInit = false;
2039  return false;
2040 }
void ResetError()
Definition: C4NetIO.h:286
#define INVALID_SOCKET
Definition: C4NetIO.h:37
virtual bool CloseBroadcast()
Definition: C4NetIO.cpp:2042
#define closesocket
Definition: C4NetIO.cpp:52

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool C4NetIOSimpleUDP::Close ( const addr_t addr)
inlinevirtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 522 of file C4NetIO.h.

522 { assert(false); return false; }
bool C4NetIOSimpleUDP::CloseBroadcast ( )
virtual

Reimplemented in C4NetIOUDP.

Definition at line 2042 of file C4NetIO.cpp.

References C4NetIO::SetError(), and SOCKET_ERROR.

Referenced by Close(), C4NetIOUDP::CloseBroadcast(), InitBroadcast(), and C4NetIOUDP::InitBroadcast().

2043 {
2044  // multicast not active?
2045  if (!fMultiCast) return true;
2046 
2047  // leave multicast group
2048  if (setsockopt(sock, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
2049  reinterpret_cast<const char *>(&MCGrpInfo), sizeof(MCGrpInfo)) == SOCKET_ERROR)
2050  {
2051  SetError("could not leave multicast group"); // to do: more error information
2052  return false;
2053  }
2054 
2055  // ok
2056  fMultiCast = false;
2057  return true;
2058 }
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:754
#define SOCKET_ERROR
Definition: C4NetIO.cpp:53

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool C4NetIOSimpleUDP::Connect ( const addr_t addr)
inlinevirtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 521 of file C4NetIO.h.

521 { assert(false); return false; }
bool C4NetIOSimpleUDP::Execute ( int  iMaxTime = TO_INF,
pollfd *  = 0 
)
virtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 2060 of file C4NetIO.cpp.

References C4NetIO::HostAddress::GetFamily(), GetSocketErrorMsg(), HaveConnResetError(), ioctlsocket, StdBuf::New(), C4NetIO::CBClass::OnDisconn(), C4NetIO::CBClass::OnPacket(), C4NetIO::ResetError(), C4NetIOPacket::SetAddr(), C4NetIO::SetError(), StdBuf::SetSize(), SOCKET_ERROR, and C4NetIO::HostAddress::UnknownFamily.

Referenced by C4NetIOUDP::DoLoopbackTest(), C4NetIOUDP::Execute(), C4NetIOUDP::InitBroadcast(), and C4StartupNetDlg::OnSec1Timer().

2061 {
2062  if (!fInit) { SetError("not yet initialized"); return false; }
2063  ResetError();
2064 
2065 #ifdef __APPLE__
2066  iMaxTime = fix_poll_timeout(iMaxTime);
2067 #endif
2068 
2069  // wait for socket / timeout
2070  WaitResult eWR = WaitForSocket(iMaxTime);
2071  if (eWR == WR_Error) return false;
2072 
2073  // cancelled / timeout?
2074  if (eWR == WR_Cancelled || eWR == WR_Timeout) return true;
2075  assert(eWR == WR_Readable);
2076 
2077  // read packets from socket
2078  for (;;)
2079  {
2080  // how much can be read?
2081 #ifdef _WIN32
2082  u_long iMaxMsgSize;
2083 #else
2084  // The FIONREAD ioctl call takes an int on unix
2085  int iMaxMsgSize;
2086 #endif
2087  if (::ioctlsocket(sock, FIONREAD, &iMaxMsgSize) == SOCKET_ERROR)
2088  {
2089  SetError("Could not determine the amount of data that can be read from socket", true);
2090  return false;
2091  }
2092 
2093  // nothing?
2094  if (!iMaxMsgSize)
2095  break;
2096  // alloc buffer
2097  C4NetIOPacket Pkt; Pkt.New(iMaxMsgSize);
2098  // read data (note: it is _not_ garantueed that iMaxMsgSize bytes are available)
2099  addr_t SrcAddr; socklen_t iSrcAddrLen = sizeof(sockaddr_in6);
2100  int iMsgSize = ::recvfrom(sock, getMBufPtr<char>(Pkt), iMaxMsgSize, 0, &SrcAddr, &iSrcAddrLen);
2101  // error?
2102  if (iMsgSize == SOCKET_ERROR)
2103  {
2104  if (HaveConnResetError())
2105  {
2106  // this is actually some kind of notification: an ICMP msg (unreachable)
2107  // came back, so callback and continue reading
2108  if (pCB) pCB->OnDisconn(SrcAddr, this, GetSocketErrorMsg());
2109  continue;
2110  }
2111  else
2112  {
2113  // this is the real thing, though
2114  SetError("could not receive data from socket", true);
2115  return false;
2116  }
2117  }
2118  // invalid address?
2119  if ((iSrcAddrLen != sizeof(sockaddr_in) && iSrcAddrLen != sizeof(sockaddr_in6)) || SrcAddr.GetFamily() == addr_t::UnknownFamily)
2120  {
2121  SetError("recvfrom returned an invalid address");
2122  return false;
2123  }
2124  // again: nothing?
2125  if (!iMsgSize)
2126  // docs say that the connection has been closed (whatever that means for a connectionless socket...)
2127  // let's just pretend it didn't happen, but stop reading.
2128  break;
2129  // fill in packet information
2130  Pkt.SetSize(iMsgSize);
2131  Pkt.SetAddr(SrcAddr);
2132  // callback
2133  if (pCB) pCB->OnPacket(Pkt, this);
2134  }
2135 
2136  // ok
2137  return true;
2138 }
void ResetError()
Definition: C4NetIO.h:286
const char * GetSocketErrorMsg(int iError)
Definition: C4NetIO.cpp:196
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:754
#define ioctlsocket
Definition: C4NetIO.cpp:51
bool HaveConnResetError()
Definition: C4NetIO.cpp:213
void SetSize(size_t inSize)
Definition: StdBuf.h:212
EndpointAddress addr_t
Definition: C4NetIO.h:212
void New(size_t inSize)
Definition: StdBuf.h:154
virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason)
Definition: C4NetIO.h:221
virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)=0
void SetAddr(const C4NetIO::addr_t &naddr)
Definition: C4NetIO.h:327
#define SOCKET_ERROR
Definition: C4NetIO.cpp:53

Here is the call graph for this function:

Here is the caller graph for this function:

bool StdSchedulerProc::ExecuteUntil ( int  iTimeout = -1)
inherited

Definition at line 46 of file StdScheduler.cpp.

References StdSchedulerProc::Execute(), and C4TimeMilliseconds::Now().

Referenced by main().

47 {
48  // Infinite?
49  if (iTimeout < 0)
50  for (;;)
51  if (!Execute())
52  return false;
53  // Calculate endpoint
54  C4TimeMilliseconds tStopTime = C4TimeMilliseconds::Now() + iTimeout;
55  for (;;)
56  {
57  // Call execute with given timeout
58  if (!Execute(std::max(iTimeout, 0)))
59  return false;
60  // Calculate timeout
62  if (tTime >= tStopTime)
63  break;
64  iTimeout = tStopTime - tTime;
65  }
66  // All ok.
67  return true;
68 }
virtual bool Execute(int iTimeout=-1, pollfd *readyfds=0)=0
static C4TimeMilliseconds Now()

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool C4NetIOSimpleUDP::GetConnStatistic ( const addr_t addr,
int *  pIRate,
int *  pORate,
int *  pLoss 
)
inlinevirtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 527 of file C4NetIO.h.

528  { assert(false); return false; }
virtual const char* C4NetIO::GetError ( ) const
inlinevirtualinherited

Definition at line 285 of file C4NetIO.h.

References StdStrBuf::getData().

Referenced by C4Network2IO::Connect(), C4NetIOUDP::DoLoopbackTest(), C4StartupNetDlg::DoRefresh(), C4DownloadDlg::GetError(), C4Network2IO::Init(), C4NetIOUDP::InitBroadcast(), C4Network2::InitLeague(), C4Game::InitNetworkFromAddress(), C4Network2::LeagueEnd(), C4Network2::LeaguePlrAuthCheck(), C4Network2::LeagueStart(), C4Network2::LeagueUpdate(), C4Network2::LeagueUpdateProcessReply(), main(), MyCBClass::OnConn(), C4ChatControl::OnConnectBtn(), MyCBClass::OnPacket(), C4StartupNetListEntry::OnReference(), C4ChatControl::ProcessInput(), C4Network2IOConnection::Send(), and C4StartupNetListEntry::SetRefQuery().

285 { return Error.getData(); }
const char * getData() const
Definition: StdBuf.h:450
StdCopyStrBuf Error
Definition: C4NetIO.h:282

Here is the call graph for this function:

Here is the caller graph for this function:

void C4NetIOSimpleUDP::GetFDs ( std::vector< struct pollfd > &  FDs)
virtual

Reimplemented from StdSchedulerProc.

Definition at line 2212 of file C4NetIO.cpp.

References INVALID_SOCKET.

2213 {
2214  // add pipe
2215  pollfd pfd = { Pipe[0], POLLIN, 0 };
2216  fds.push_back(pfd);
2217  // add socket
2218  if (sock != INVALID_SOCKET)
2219  {
2220  pollfd pfd = { sock, POLLIN, 0 };
2221  fds.push_back(pfd);
2222  }
2223 }
#define INVALID_SOCKET
Definition: C4NetIO.h:37
std::vector< C4NetIO::HostAddress > C4NetIO::GetLocalAddresses ( )
staticinherited

Definition at line 632 of file C4NetIO.cpp.

References C4NetIO::HostAddress::IsLoopback(), and C4NetIO::HostAddress::SetHost().

Referenced by C4Network2Client::AddLocalAddrs(), and C4NetIOUDP::InitBroadcast().

633 {
634  std::vector<HostAddress> result;
635 
636 #ifdef HAVE_WINSOCK
637  HostAddress addr;
638  const size_t BUFFER_SIZE = 16000;
639  PIP_ADAPTER_ADDRESSES addresses = nullptr;
640  for (int i = 0; i < 3; ++i)
641  {
642  addresses = (PIP_ADAPTER_ADDRESSES) realloc(addresses, BUFFER_SIZE * (i+1));
643  if (!addresses)
644  // allocation failed
645  return result;
646  ULONG bufsz = BUFFER_SIZE * (i+1);
647  DWORD rv = GetAdaptersAddresses(AF_UNSPEC,
648  GAA_FLAG_SKIP_ANYCAST|GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER|GAA_FLAG_SKIP_FRIENDLY_NAME,
649  nullptr, addresses, &bufsz);
650  if (rv == ERROR_BUFFER_OVERFLOW)
651  // too little space, try again
652  continue;
653  if (rv != NO_ERROR)
654  {
655  // Something else happened
656  free(addresses);
657  return result;
658  }
659  // All okay, add addresses
660  for (PIP_ADAPTER_ADDRESSES address = addresses; address; address = address->Next)
661  {
662  for (PIP_ADAPTER_UNICAST_ADDRESS unicast = address->FirstUnicastAddress; unicast; unicast = unicast->Next)
663  {
664  addr.SetHost(unicast->Address.lpSockaddr);
665  if (addr.IsLoopback())
666  continue;
667  result.push_back(addr);
668  }
669  }
670  }
671  free(addresses);
672 #else
673  bool have_ipv6 = false;
674 
675 #ifdef __linux__
676  // Get IPv6 addresses on Linux from procfs which allows filtering deprecated privacy addresses.
677  FILE *f = fopen("/proc/net/if_inet6", "r");
678  if (f)
679  {
680  sockaddr_in6 sa6 = sockaddr_in6();
681  sa6.sin6_family = AF_INET6;
682  auto a6 = sa6.sin6_addr.s6_addr;
683  uint8_t if_idx, plen, scope, flags;
684  char devname[20];
685  while (fscanf(f, "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx %02hhx %02hhx %02hhx %02hhx %20s\n",
686  &a6[0], &a6[1], &a6[2], &a6[3], &a6[4], &a6[5], &a6[6], &a6[7],
687  &a6[8], &a6[9], &a6[10], &a6[11], &a6[12], &a6[13], &a6[14], &a6[15],
688  &if_idx, &plen, &scope, &flags, devname) != EOF)
689  {
690  // Skip loopback and deprecated addresses.
691  if (scope == IPV6_ADDR_LOOPBACK || flags & IFA_F_DEPRECATED)
692  continue;
693  sa6.sin6_scope_id = scope == IPV6_ADDR_LINKLOCAL ? if_idx : 0;
694  result.emplace_back((sockaddr*) &sa6);
695  }
696  have_ipv6 = result.size() > 0;
697  fclose(f);
698  }
699 #endif
700 
701  struct ifaddrs* addrs;
702  if (getifaddrs(&addrs) < 0)
703  return result;
704  for (struct ifaddrs* ifaddr = addrs; ifaddr != nullptr; ifaddr = ifaddr->ifa_next)
705  {
706  struct sockaddr* ad = ifaddr->ifa_addr;
707  if (ad == nullptr) continue;
708 
709  if ((ad->sa_family == AF_INET || (!have_ipv6 && ad->sa_family == AF_INET6)) && (~ifaddr->ifa_flags & IFF_LOOPBACK)) // Choose only non-loopback IPv4/6 devices
710  {
711  result.emplace_back(ad);
712  }
713  }
714  freeifaddrs(addrs);
715 #endif
716 
717  return result;
718 }
uint32_t DWORD

Here is the call graph for this function:

Here is the caller graph for this function:

const addr_t& C4NetIOSimpleUDP::getMCAddr ( ) const
inlineprotected

Definition at line 555 of file C4NetIO.h.

Referenced by C4NetIOUDP::SendDirect().

555 { return MCAddr; }

Here is the caller graph for this function:

bool C4NetIOSimpleUDP::getMCLoopback ( ) const
inlineprotected

Definition at line 559 of file C4NetIO.h.

Referenced by C4NetIOUDP::DoLoopbackTest(), and C4NetIOUDP::InitBroadcast().

559 { return fMCLoopback; }

Here is the caller graph for this function:

C4TimeMilliseconds StdSchedulerProc::GetNextTick ( C4TimeMilliseconds  tNow)
virtualinherited

Reimplemented in C4NetIOUDP, C4Network2HTTPClient, C4Network2IO, and CStdTimerProc.

Definition at line 128 of file StdScheduler.cpp.

References C4TimeMilliseconds::PositiveInfinity.

Referenced by C4Network2HTTPClient::GetNextTick().

Here is the caller graph for this function:

virtual bool C4NetIOSimpleUDP::GetStatistic ( int *  pBroadcastRate)
inlinevirtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 526 of file C4NetIO.h.

526 { assert(false); return false; }
bool C4NetIOSimpleUDP::Init ( uint16_t  iPort = addr_t::IPPORT_NONE)
virtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP, C4Network2IODiscoverClient, and C4Network2IODiscover.

Definition at line 1858 of file C4NetIO.cpp.

References C4NetIO::HostAddress::Any, Close(), C4NetIO::InitIPv6Socket(), INVALID_SOCKET, C4NetIO::ResetError(), C4NetIO::SetError(), C4NetIO::EndpointAddress::SetPort(), SOCK_CLOEXEC, and SOCKET_ERROR.

Referenced by C4Network2IODiscover::Init(), C4Network2IODiscoverClient::Init(), and C4NetIOUDP::Init().

1859 {
1860  // reset error
1861  ResetError();
1862 
1863  // already initialized? close first
1864  if (fInit) Close();
1865 
1866 #ifdef HAVE_WINSOCK
1867  // init winsock
1868  if (!AcquireWinSock())
1869  {
1870  SetError("could not start winsock");
1871  return false;
1872  }
1873 #endif
1874 
1875  // create sockets
1876  if ((sock = ::socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP)) == INVALID_SOCKET)
1877  {
1878  SetError("could not create socket", true);
1879  return false;
1880  }
1881 
1882  if (!InitIPv6Socket(sock))
1883  return false;
1884 
1885  // set reuse socket option
1886  if (::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&fAllowReUse), sizeof fAllowReUse) == SOCKET_ERROR)
1887  {
1888  SetError("could not set reuse options", true);
1889  return false;
1890  }
1891 
1892  // bind socket
1893  iPort = inPort;
1894  addr_t naddr = addr_t::Any;
1895  naddr.SetPort(iPort);
1896  if (::bind(sock, &naddr, sizeof(naddr)) == SOCKET_ERROR)
1897  {
1898  SetError("could not bind socket", true);
1899  return false;
1900  }
1901 
1902 #ifdef STDSCHEDULER_USE_EVENTS
1903 
1904  // create event
1905  if ((hEvent = WSACreateEvent()) == WSA_INVALID_EVENT)
1906  {
1907  SetError("could not create event", true);
1908  return false;
1909  }
1910 
1911  // set event for socket
1912  if (WSAEventSelect(sock, hEvent, FD_READ | FD_CLOSE) == SOCKET_ERROR)
1913  {
1914  SetError("could not select event", true);
1915  return false;
1916  }
1917 
1918 #else
1919 
1920  // disable blocking
1921  if (::fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) == SOCKET_ERROR)
1922  {
1923  // set error
1924  SetError("could not disable blocking", true);
1925  return false;
1926  }
1927 
1928  // create pipe
1929  if (pipe(Pipe) != 0)
1930  {
1931  SetError("could not create pipe", true);
1932  return false;
1933  }
1934 
1935 #endif
1936 
1937  // set flags
1938  fInit = true;
1939  fMultiCast = false;
1940 
1941  // ok, that's all for know.
1942  // call InitBroadcast for more initialization fun
1943  return true;
1944 }
void ResetError()
Definition: C4NetIO.h:286
#define INVALID_SOCKET
Definition: C4NetIO.h:37
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:754
bool InitIPv6Socket(SOCKET socket)
Definition: C4NetIO.cpp:734
EndpointAddress addr_t
Definition: C4NetIO.h:212
#define SOCK_CLOEXEC
Definition: C4NetIO.h:51
virtual bool Close()
Definition: C4NetIO.cpp:2001
#define SOCKET_ERROR
Definition: C4NetIO.cpp:53

Here is the call graph for this function:

Here is the caller graph for this function:

bool C4NetIOSimpleUDP::InitBroadcast ( addr_t pBroadcastAddr)
virtual

Reimplemented in C4NetIOUDP.

Definition at line 1946 of file C4NetIO.cpp.

References CloseBroadcast(), C4NetIO::HostAddress::GetFamily(), C4NetIO::EndpointAddress::GetPort(), C4NetIO::HostAddress::IPv6, C4NetIO::HostAddress::IsMulticast(), C4NetIO::ResetError(), C4NetIO::SetError(), SetMCLoopback(), and SOCKET_ERROR.

Referenced by C4Network2IODiscover::Init(), C4Network2IODiscoverClient::Init(), and C4NetIOUDP::InitBroadcast().

1947 {
1948  // no error... yet
1949  ResetError();
1950 
1951  // security
1952  if (!pBroadcastAddr) return false;
1953 
1954  // Init() has to be called first
1955  if (!fInit) return false;
1956  // already activated?
1957  if (fMultiCast) CloseBroadcast();
1958 
1959  // broadcast addr valid?
1960  if (!pBroadcastAddr->IsMulticast() || pBroadcastAddr->GetFamily() != HostAddress::IPv6)
1961  {
1962  SetError("invalid broadcast address (only IPv6 multicast addresses are supported)");
1963  return false;
1964  }
1965  if (pBroadcastAddr->GetPort() != iPort)
1966  {
1967  SetError("invalid broadcast address (different port)");
1968  return false;
1969  }
1970 
1971  // set mc ttl to somewhat about "same net"
1972  int TTL = 16;
1973  if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, reinterpret_cast<char*>(&TTL), sizeof(TTL)) == SOCKET_ERROR)
1974  {
1975  SetError("could not set mc ttl", true);
1976  return false;
1977  }
1978 
1979  // set up multicast group information
1980  this->MCAddr = *pBroadcastAddr;
1981  MCGrpInfo.ipv6mr_multiaddr = static_cast<sockaddr_in6>(MCAddr).sin6_addr;
1982  // TODO: do multicast on all interfaces?
1983  MCGrpInfo.ipv6mr_interface = 0; // default interface
1984 
1985  // join multicast group
1986  if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
1987  reinterpret_cast<const char *>(&MCGrpInfo), sizeof(MCGrpInfo)) == SOCKET_ERROR)
1988  {
1989  SetError("could not join multicast group"); // to do: more error information
1990  return false;
1991  }
1992 
1993  // (try to) disable loopback (will set fLoopback accordingly)
1994  SetMCLoopback(false);
1995 
1996  // ok
1997  fMultiCast = true;
1998  return true;
1999 }
void ResetError()
Definition: C4NetIO.h:286
bool SetMCLoopback(int fLoopback)
Definition: C4NetIO.cpp:2250
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:754
virtual bool CloseBroadcast()
Definition: C4NetIO.cpp:2042
#define SOCKET_ERROR
Definition: C4NetIO.cpp:53

Here is the call graph for this function:

Here is the caller graph for this function:

bool C4NetIO::InitIPv6Socket ( SOCKET  socket)
protectedinherited

Definition at line 734 of file C4NetIO.cpp.

References C4NetIO::SetError(), and SOCKET_ERROR.

Referenced by C4NetIOTCP::Connect(), Init(), and C4NetIOTCP::Listen().

735 {
736  int opt = 0;
737  if (setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&opt), sizeof(opt)) == SOCKET_ERROR)
738  {
739  SetError("could not enable dual-stack socket", true);
740  return false;
741  }
742 
743 #ifdef IPV6_ADDR_PREFERENCES
744  // Prefer stable addresses. This should prevent issues with address
745  // deprecation while a match is running. No error handling - if the call
746  // fails, we just take any address.
747  opt = IPV6_PREFER_SRC_PUBLIC;
748  setsockopt(socket, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, reinterpret_cast<char*>(&opt), sizeof(opt));
749 #endif
750 
751  return true;
752 }
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:754
#define SOCKET_ERROR
Definition: C4NetIO.cpp:53

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool StdSchedulerProc::IsLowPriority ( )
inlinevirtualinherited

Definition at line 86 of file StdScheduler.h.

86 { return false; }
virtual bool C4NetIO::IsNotify ( )
inlinevirtualinherited

Reimplemented from StdSchedulerProc.

Definition at line 259 of file C4NetIO.h.

259 { return true; }
bool StdSchedulerProc::IsSignaled ( )
inherited
void C4NetIO::ResetError ( )
inlineinherited

Definition at line 286 of file C4NetIO.h.

References StdStrBuf::Clear().

Referenced by C4NetIO::C4NetIO(), C4NetIOTCP::Close(), Close(), C4NetIOUDP::CloseBroadcast(), C4Network2IO::Connect(), Execute(), C4NetIOUDP::Execute(), C4Network2RefClient::GetReferences(), Init(), InitBroadcast(), C4NetIOUDP::InitBroadcast(), C4Network2HTTPClient::Query(), C4Network2IOConnection::Send(), Send(), and C4Network2HTTPClient::SetServer().

286 { Error.Clear(); }
void Clear()
Definition: StdBuf.h:474
StdCopyStrBuf Error
Definition: C4NetIO.h:282

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool C4NetIO::Send ( const class C4NetIOPacket rPacket)
pure virtualinherited

Referenced by main(), MyCBClass::OnConn(), MyCBClass::OnPacket(), C4Network2IOConnection::Send(), and C4Network2IO::SendPuncherPacket().

Here is the caller graph for this function:

bool C4NetIOSimpleUDP::Send ( const C4NetIOPacket rPacket)
virtual

Reimplemented in C4NetIOUDP.

Definition at line 2140 of file C4NetIO.cpp.

References C4NetIOPacket::getAddr(), StdBuf::getSize(), HaveWouldBlockError(), C4NetIO::ResetError(), and C4NetIO::SetError().

Referenced by C4Network2IODiscover::Announce(), Broadcast(), C4NetIOUDP::SendDirect(), and C4Network2IODiscoverClient::StartDiscovery().

2141 {
2142  if (!fInit) { SetError("not yet initialized"); return false; }
2143 
2144  // send it
2145  C4NetIO::addr_t addr = rPacket.getAddr();
2146  if (::sendto(sock, getBufPtr<char>(rPacket), rPacket.getSize(), 0,
2147  &addr, sizeof(addr))
2148  != int(rPacket.getSize()) &&
2150  {
2151  SetError("socket sendto failed", true);
2152  return false;
2153  }
2154 
2155  // ok
2156  ResetError();
2157  return true;
2158 }
void ResetError()
Definition: C4NetIO.h:286
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:754
size_t getSize() const
Definition: StdBuf.h:109
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:316
bool HaveWouldBlockError()
Definition: C4NetIO.cpp:209

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool C4NetIOSimpleUDP::SetBroadcast ( const addr_t addr,
bool  fSet = true 
)
inlinevirtual

Implements C4NetIO.

Reimplemented in C4NetIOUDP.

Definition at line 524 of file C4NetIO.h.

524 { assert(false); return false; }
virtual void C4NetIO::SetCallback ( CBClass pnCallback)
pure virtualinherited

Referenced by C4NetIOMan::AddIO(), and C4Network2IO::Init().

Here is the caller graph for this function:

virtual void C4NetIOSimpleUDP::SetCallback ( CBClass *  pnCallback)
inlinevirtual

Reimplemented in C4NetIOUDP.

Definition at line 572 of file C4NetIO.h.

Referenced by C4Network2IODiscover::C4Network2IODiscover(), C4Network2IODiscoverClient::C4Network2IODiscoverClient(), C4Network2IODiscover::Init(), C4Network2IODiscoverClient::Init(), and C4NetIOUDP::Init().

572 { pCB = pnCallback; };

Here is the caller graph for this function:

void C4NetIO::SetError ( const char *  strnError,
bool  fSockErr = false 
)
protectedinherited

Definition at line 754 of file C4NetIO.cpp.

References StdStrBuf::Copy(), C4NetIO::Error, StdStrBuf::Format(), GetSocketErrorMsg(), and HaveSocketError().

Referenced by C4NetIOTCP::Accept(), CloseBroadcast(), C4Network2IRCClient::Connect(), C4NetIOTCP::Connect(), C4NetIOUDP::DoLoopbackTest(), C4NetIOTCP::Execute(), Execute(), C4NetIOUDP::Execute(), C4Network2RefClient::GetReferences(), C4Network2UpdateClient::GetUpdateURL(), C4Network2UpdateClient::GetVersion(), C4NetIOTCP::Init(), Init(), InitBroadcast(), C4NetIOUDP::InitBroadcast(), C4NetIO::InitIPv6Socket(), C4Network2IRCClient::Join(), C4NetIOTCP::Listen(), C4Network2IRCClient::Send(), Send(), C4Network2HTTPClient::SetServer(), C4NetIOTCP::UnBlock(), and UnBlock().

755 {
756  fSockErr &= HaveSocketError();
757  if (fSockErr)
758  Error.Format("%s (%s)", strnError, GetSocketErrorMsg());
759  else
760  Error.Copy(strnError);
761 }
const char * GetSocketErrorMsg(int iError)
Definition: C4NetIO.cpp:196
StdCopyStrBuf Error
Definition: C4NetIO.h:282
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:181
bool HaveSocketError()
Definition: C4NetIO.cpp:205
void Copy()
Definition: StdBuf.h:475

Here is the call graph for this function:

Here is the caller graph for this function:

bool C4NetIOSimpleUDP::SetMCLoopback ( int  fLoopback)
protected

Definition at line 2250 of file C4NetIO.cpp.

References iSize, and SOCKET_ERROR.

Referenced by C4NetIOUDP::DoLoopbackTest(), C4Network2IODiscover::Init(), C4Network2IODiscoverClient::Init(), InitBroadcast(), and C4NetIOUDP::InitBroadcast().

2251 {
2252  // enable/disable MC loopback
2253  setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), sizeof fLoopback);
2254  // read result
2255  socklen_t iSize = sizeof(fLoopback);
2256  if (getsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), &iSize) == SOCKET_ERROR)
2257  return false;
2258  fMCLoopback = !! fLoopback;
2259  return true;
2260 }
int iSize
Definition: TstC4NetIO.cpp:35
#define SOCKET_ERROR
Definition: C4NetIO.cpp:53

Here is the caller graph for this function:

void C4NetIOSimpleUDP::SetReUseAddress ( bool  fAllow)
protected

Definition at line 2262 of file C4NetIO.cpp.

Referenced by C4Network2IODiscover::Init(), and C4Network2IODiscoverClient::Init().

2263 {
2264  fAllowReUse = fAllow;
2265 }

Here is the caller graph for this function:

virtual uint32_t StdSchedulerProc::TimerInterval ( )
inlinevirtualinherited

Reimplemented in CStdTimerProc.

Definition at line 88 of file StdScheduler.h.

Referenced by SCHAdditions::assignAdditionForProc:.

88 { return 0; }

Here is the caller graph for this function:

void C4NetIOSimpleUDP::UnBlock ( )
virtual

Definition at line 2203 of file C4NetIO.cpp.

References C4NetIO::SetError().

2204 {
2205  // write one character to the pipe, this will unblock everything that
2206  // waits for the FD set returned by GetFDs.
2207  char c = 42;
2208  if (write(Pipe[1], &c, 1) == -1)
2209  SetError("write failed");
2210 }
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:754

Here is the call graph for this function:

Member Data Documentation

const int C4NetIO::TO_INF = -1
staticinherited

The documentation for this class was generated from the following files: