EMANE  1.2.1
datagramsocket.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "datagramsocket.h"
34 #include "socketexception.h"
35 #include <cstring>
36 #include <sys/socket.h>
37 
39 
41  bool bReuseAddress)
42 {
43  open(address,
44  bReuseAddress);
45 }
46 
48  bool bReuseAddress)
49 {
50  if(iSock_ != -1)
51  {
52  close();
53  }
54 
55  addr_ = address;
56 
57  if((iSock_ = socket(address.getFamily(),
58  SOCK_DGRAM,
59  0)) == -1)
60  {
61  throw SocketException(strerror(errno));
62  }
63 
64  if(bReuseAddress)
65  {
66  int iOption{1};
67 
68  if(setsockopt(iSock_,
69  SOL_SOCKET,
70  SO_REUSEADDR,
71  reinterpret_cast<void*>(&iOption),
72  sizeof(iOption)) < 0)
73  {
74  throw makeException<SocketException>("setsockopt SO_REUSEADDR: %s",
75  strerror(errno));
76 
77  }
78  }
79 
80 
81  if(bind(iSock_,addr_.getSockAddr(),addr_.getAddrLength()) < 0)
82  {
83  throw makeException<SocketException>("bind: %s",
84  strerror(errno));
85  }
86 
87 }
88 
90 
92 {
93  return iSock_;
94 }
95 
96 
97 ssize_t EMANE::DatagramSocket::send(const iovec *iov,
98  int iovcnt,
99  const INETAddr & remoteAddress,
100  int flags) const
101 {
102  msghdr msg;
103  memset(&msg,0,sizeof(msg));
104 
105  msg.msg_iov = const_cast<iovec *>(iov);
106  msg.msg_iovlen = iovcnt;
107 
108  msg.msg_name = remoteAddress.getSockAddr();
109  msg.msg_namelen = remoteAddress.getAddrLength();
110 
111  return sendmsg(iSock_,&msg,flags);
112 }
113 
114 ssize_t EMANE::DatagramSocket::recv(void * buf,
115  size_t len,
116  int flags)
117 {
118  return ::recv(iSock_,buf,len,flags);
119 }
120 
122 {
123  if(addr_.isIPv4())
124  {
125  sockaddr_in addr;
126  socklen_t len = sizeof(addr);
127 
128  if(getsockname(iSock_, reinterpret_cast<sockaddr*>(&addr), &len))
129  {
130  throw makeException<SocketException>("getsockname: %s",
131  strerror(errno));
132  }
133 
134  return INETAddr{addr};
135  }
136  else
137  {
138  sockaddr_in6 addr;
139  socklen_t len = sizeof(addr);
140 
141  if(getsockname(iSock_, reinterpret_cast<sockaddr*>(&addr), &len))
142  {
143  throw makeException<SocketException>("getsockname: %s",
144  strerror(errno));
145  }
146 
147  return INETAddr{addr};
148  }
149 }
void close()
Definition: socket.cc:40
socklen_t getAddrLength() const
Definition: inetaddr.cc:404
void open(const INETAddr &address, bool bReuseAddress=false)
sockaddr * getSockAddr() const
Definition: inetaddr.cc:399
ssize_t send(const iovec *iov, int iovcnt, const INETAddr &remoteAddress, int flags=0) const
bool isIPv4() const
Definition: inetaddr.cc:384
int getFamily() const
Definition: inetaddr.cc:394
int iSock_
Definition: socket.h:55
ssize_t recv(void *buf, size_t len, int flags=0)
INETAddr getLocalAddress() const