2 Copyright (C) 2008-2011 Romain Moret at Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "JackNetUnixSocket.h"
21 #include "JackError.h"
28 //utility *********************************************************************************************************
29 int GetHostName(char * name
, int size
)
31 if (gethostname(name
, size
) == SOCKET_ERROR
) {
32 jack_error("Can't get 'hostname' : %s", strerror(NET_ERROR_CODE
));
33 strcpy(name
, "default");
39 //construct/destruct***********************************************************************************************
40 JackNetUnixSocket::JackNetUnixSocket()
45 fSendAddr
.sin_family
= AF_INET
;
46 fSendAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
47 memset(&fSendAddr
.sin_zero
, 0, 8);
48 fRecvAddr
.sin_family
= AF_INET
;
49 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
50 memset(&fRecvAddr
.sin_zero
, 0, 8);
53 JackNetUnixSocket::JackNetUnixSocket(const char* ip
, int port
)
58 fSendAddr
.sin_family
= AF_INET
;
59 fSendAddr
.sin_port
= htons(port
);
60 inet_aton(ip
, &fSendAddr
.sin_addr
);
61 memset(&fSendAddr
.sin_zero
, 0, 8);
62 fRecvAddr
.sin_family
= AF_INET
;
63 fRecvAddr
.sin_port
= htons(port
);
64 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
65 memset(&fRecvAddr
.sin_zero
, 0, 8);
68 JackNetUnixSocket::JackNetUnixSocket(const JackNetUnixSocket
& socket
)
73 fSendAddr
= socket
.fSendAddr
;
74 fRecvAddr
= socket
.fRecvAddr
;
77 JackNetUnixSocket::~JackNetUnixSocket()
82 JackNetUnixSocket
& JackNetUnixSocket::operator=(const JackNetUnixSocket
& socket
)
84 if (this != &socket
) {
87 fSendAddr
= socket
.fSendAddr
;
88 fRecvAddr
= socket
.fRecvAddr
;
93 //socket***********************************************************************************************************
94 int JackNetUnixSocket::NewSocket()
100 fSockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
102 /* Enable address reuse */
105 if ((res
= setsockopt(fSockfd
, SOL_SOCKET
, SO_REUSEPORT
, &on
, sizeof(on
))) < 0) {
107 if ((res
= setsockopt(fSockfd
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
))) < 0) {
109 StrError(NET_ERROR_CODE
);
114 bool JackNetUnixSocket::IsLocal(char* ip
)
116 if (strcmp(ip
, "127.0.0.1") == 0) {
121 gethostname(host_name
, sizeof(host_name
));
123 struct hostent
* host
= gethostbyname(host_name
);
125 for (int i
= 0; host
->h_addr_list
[i
] != 0; ++i
) {
127 memcpy(&addr
, host
->h_addr_list
[i
], sizeof(struct in_addr
));
128 if (strcmp(inet_ntoa(addr
), ip
) == 0) {
138 int JackNetUnixSocket::Bind()
140 return bind(fSockfd
, reinterpret_cast<socket_address_t
*>(&fRecvAddr
), sizeof(socket_address_t
));
143 int JackNetUnixSocket::BindWith(const char* ip
)
145 int addr_conv
= inet_aton(ip
, &fRecvAddr
.sin_addr
);
151 int JackNetUnixSocket::BindWith(int port
)
153 fRecvAddr
.sin_port
= htons(port
);
157 int JackNetUnixSocket::Connect()
159 return connect(fSockfd
, reinterpret_cast<socket_address_t
*>(&fSendAddr
), sizeof(socket_address_t
));
162 int JackNetUnixSocket::ConnectTo(const char* ip
)
164 int addr_conv
= inet_aton(ip
, &fSendAddr
.sin_addr
);
170 void JackNetUnixSocket::Close()
177 void JackNetUnixSocket::Reset()
179 fSendAddr
.sin_family
= AF_INET
;
180 fSendAddr
.sin_port
= htons(fPort
);
181 fSendAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
182 memset(&fSendAddr
.sin_zero
, 0, 8);
183 fRecvAddr
.sin_family
= AF_INET
;
184 fRecvAddr
.sin_port
= htons(fPort
);
185 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
186 memset(&fRecvAddr
.sin_zero
, 0, 8);
189 bool JackNetUnixSocket::IsSocket()
191 return(fSockfd
) ? true : false;
194 //IP/PORT***********************************************************************************************************
195 void JackNetUnixSocket::SetPort(int port
)
198 fSendAddr
.sin_port
= htons(port
);
199 fRecvAddr
.sin_port
= htons(port
);
202 int JackNetUnixSocket::GetPort()
207 //address***********************************************************************************************************
208 int JackNetUnixSocket::SetAddress(const char* ip
, int port
)
210 int addr_conv
= inet_aton(ip
, &fSendAddr
.sin_addr
);
213 fSendAddr
.sin_port
= htons(port
);
217 char* JackNetUnixSocket::GetSendIP()
219 return inet_ntoa(fSendAddr
.sin_addr
);
222 char* JackNetUnixSocket::GetRecvIP()
224 return inet_ntoa(fRecvAddr
.sin_addr
);
227 //utility************************************************************************************************************
228 int JackNetUnixSocket::GetName(char* name
)
230 return gethostname(name
, 255);
233 int JackNetUnixSocket::JoinMCastGroup(const char* ip
)
235 struct ip_mreq multicast_req
;
236 inet_aton(ip
, &multicast_req
.imr_multiaddr
);
237 multicast_req
.imr_interface
.s_addr
= htonl(INADDR_ANY
);
238 return SetOption(IPPROTO_IP
, IP_ADD_MEMBERSHIP
, &multicast_req
, sizeof(multicast_req
));
241 //options************************************************************************************************************
242 int JackNetUnixSocket::SetOption(int level
, int optname
, const void* optval
, socklen_t optlen
)
244 return setsockopt(fSockfd
, level
, optname
, optval
, optlen
);
247 int JackNetUnixSocket::GetOption(int level
, int optname
, void* optval
, socklen_t
* optlen
)
249 return getsockopt(fSockfd
, level
, optname
, optval
, optlen
);
252 //timeout************************************************************************************************************
254 #if defined(__sun__) || defined(sun)
255 int JackNetUnixSocket::SetTimeOut(int us
)
260 if ((flags
= fcntl(fSockfd
, F_GETFL
, 0)) < 0) {
261 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_GETFL");
266 if (fcntl(fSockfd
, F_SETFL
, flags
) < 0) {
267 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_SETFL");
274 int JackNetUnixSocket::WaitRead()
282 tv
.tv_sec
= fTimeOut
/ 1000000;
283 tv
.tv_usec
= fTimeOut
% 1000000;
286 FD_SET(fSockfd
, &fdset
);
289 res
= select(fSockfd
+ 1, &fdset
, NULL
, NULL
, &tv
);
290 } while(res
< 0 && errno
== EINTR
);
294 } else if (res
== 0) {
303 int JackNetUnixSocket::WaitWrite()
311 tv
.tv_sec
= fTimeOut
/ 1000000;
312 tv
.tv_usec
= fTimeOut
% 1000000;
315 FD_SET(fSockfd
, &fdset
);
318 res
= select(fSockfd
+ 1, NULL
, &fdset
, NULL
, &tv
);
319 } while(res
< 0 && errno
== EINTR
);
323 } else if (res
== 0) {
333 int JackNetUnixSocket::SetTimeOut(int us
)
335 jack_log("JackNetUnixSocket::SetTimeout %d usecs", us
);
336 struct timeval timeout
;
341 timeout
.tv_usec
= us
;
344 float sec
= float(us
) / 1000000.f
;
345 timeout
.tv_sec
= (int)sec
;
346 float usec
= (sec
- float(timeout
.tv_sec
)) * 1000000;
347 timeout
.tv_usec
=(int)usec
;
349 return SetOption(SOL_SOCKET
, SO_RCVTIMEO
, &timeout
, sizeof(timeout
));
353 //local loop**********************************************************************************************************
354 int JackNetUnixSocket::SetLocalLoop()
357 return SetOption(IPPROTO_IP
, IP_MULTICAST_LOOP
, &disable
, sizeof(disable
));
360 //network operations**************************************************************************************************
361 int JackNetUnixSocket::SendTo(const void* buffer
, size_t nbytes
, int flags
)
363 #if defined(__sun__) || defined(sun)
367 return sendto(fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*>(&fSendAddr
), sizeof(socket_address_t
));
370 int JackNetUnixSocket::SendTo(const void* buffer
, size_t nbytes
, int flags
, const char* ip
)
372 int addr_conv
= inet_aton(ip
, &fSendAddr
.sin_addr
);
375 #if defined(__sun__) || defined(sun)
379 return SendTo(buffer
, nbytes
, flags
);
382 int JackNetUnixSocket::Send(const void* buffer
, size_t nbytes
, int flags
)
384 #if defined(__sun__) || defined(sun)
388 return send(fSockfd
, buffer
, nbytes
, flags
);
391 int JackNetUnixSocket::RecvFrom(void* buffer
, size_t nbytes
, int flags
)
393 socklen_t addr_len
= sizeof(socket_address_t
);
394 #if defined(__sun__) || defined(sun)
398 return recvfrom(fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*>(&fRecvAddr
), &addr_len
);
401 int JackNetUnixSocket::Recv(void* buffer
, size_t nbytes
, int flags
)
403 #if defined(__sun__) || defined(sun)
407 return recv(fSockfd
, buffer
, nbytes
, flags
);
410 int JackNetUnixSocket::CatchHost(void* buffer
, size_t nbytes
, int flags
)
412 socklen_t addr_len
= sizeof(socket_address_t
);
413 #if defined(__sun__) || defined(sun)
417 return recvfrom(fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*>(&fSendAddr
), &addr_len
);
420 net_error_t
JackNetUnixSocket::GetError()
436 return NET_CONN_ERROR
;
439 //return NET_OP_ERROR;
440 return NET_CONN_ERROR
;