This is Unofficial EPICS BASE Doxygen Site
blockingUDPConnector.cpp
Go to the documentation of this file.
1 
7 #include <sys/types.h>
8 
9 #include <osiSock.h>
10 
11 #define epicsExportSharedSymbols
12 #include <pv/blockingUDP.h>
13 #include <pv/remote.h>
14 #include <pv/logger.h>
15 
16 using namespace std;
17 using namespace epics::pvData;
18 
19 namespace {
20 struct closer {
21  epics::pvAccess::BlockingUDPTransport::shared_pointer P;
22  closer(const epics::pvAccess::BlockingUDPTransport::shared_pointer& P) :P(P) {}
23  void operator()(epics::pvAccess::BlockingUDPTransport*) {
24  try{
25  P->close();
26  }catch(...){
27  P.reset();
28  throw;
29  }
30  P.reset();
31  }
32 };
33 }
34 
35 namespace epics {
36 namespace pvAccess {
37 
38 BlockingUDPTransport::shared_pointer BlockingUDPConnector::connect(ResponseHandler::shared_pointer const & responseHandler,
39  osiSockAddr& bindAddress,
40  int8 transportRevision)
41 {
42  SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
43  if(socket==INVALID_SOCKET) {
44  char errStr[64];
45  epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
46  LOG(logLevelError, "Error creating socket: %s.", errStr);
47  return BlockingUDPTransport::shared_pointer();
48  }
49 
50  int optval = 1;
51  int retval = ::setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval));
52  if(retval<0)
53  {
54  char errStr[64];
55  epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
56  LOG(logLevelError, "Error setting SO_BROADCAST: %s.", errStr);
57  epicsSocketDestroy (socket);
58  return BlockingUDPTransport::shared_pointer();
59  }
60 
61  /*
62  IPv4 multicast addresses are defined by the leading address bits of 1110,
63  originating from the classful network design of the early Internet when this
64  group of addresses was designated as Class D. The Classless Inter-Domain Routing (CIDR)
65  prefix of this group is 224.0.0.0/4.
66  The group includes the addresses from 224.0.0.0 to 239.255.255.255.
67  Address assignments from within this range are specified in RFC 5771,
68  an Internet Engineering Task Force (IETF) Best Current Practice document (BCP 51).*/
69 
70 
71  // set SO_REUSEADDR or SO_REUSEPORT, OS dependant
73 
74  retval = ::bind(socket, (sockaddr*)&(bindAddress.sa), sizeof(sockaddr));
75  if(retval<0) {
76  char ip[24];
77  sockAddrToDottedIP((sockaddr*)&(bindAddress.sa), ip, sizeof(ip));
78  char errStr[64];
79  epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
80  LOG(logLevelError, "Error binding socket %s: %s.", ip, errStr);
81  epicsSocketDestroy (socket);
82  return BlockingUDPTransport::shared_pointer();
83  }
84 
85  // sockets are blocking by default
86  BlockingUDPTransport::shared_pointer transport(new BlockingUDPTransport(_serverFlag, responseHandler,
87  socket, bindAddress, transportRevision));
88  transport->internal_this = transport;
89 
90  // the worker thread holds a strong ref, which is released by transport->close()
91  BlockingUDPTransport::shared_pointer ret(transport.get(), closer(transport));
92 
93  return ret;
94 }
95 
96 }
97 }
int8_t int8
Definition: pvType.h:75
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
unsigned epicsStdCall sockAddrToDottedIP(const struct sockaddr *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:118
#define INVALID_SOCKET
Definition: osdSock.h:32
struct sockaddr sa
Definition: osiSock.h:158
Definition: memory.hpp:41
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
void epicsStdCall epicsSocketEnableAddressUseForDatagramFanout(SOCKET s)
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate(int domain, int type, int protocol)
Definition: osdSock.c:71
#define LOG(level, format,...)
Definition: logger.h:48
pvData
Definition: monitor.h:428
int SOCKET
Definition: osdSock.h:31