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"
26 //utility *********************************************************************************************************
27 int GetHostName(char * name
, int size
)
29 if (gethostname(name
, size
) == SOCKET_ERROR
) {
30 jack_error("Can't get 'hostname' : %s", strerror(NET_ERROR_CODE
));
31 strcpy(name
, "default");
37 //construct/destruct***********************************************************************************************
38 JackNetUnixSocket::JackNetUnixSocket()
43 fSendAddr
.sin_family
= AF_INET
;
44 fSendAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
45 memset(&fSendAddr
.sin_zero
, 0, 8);
46 fRecvAddr
.sin_family
= AF_INET
;
47 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
48 memset(&fRecvAddr
.sin_zero
, 0, 8);
51 JackNetUnixSocket::JackNetUnixSocket(const char* ip
, int port
)
56 fSendAddr
.sin_family
= AF_INET
;
57 fSendAddr
.sin_port
= htons(port
);
58 inet_aton(ip
, &fSendAddr
.sin_addr
);
59 memset(&fSendAddr
.sin_zero
, 0, 8);
60 fRecvAddr
.sin_family
= AF_INET
;
61 fRecvAddr
.sin_port
= htons(port
);
62 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
63 memset(&fRecvAddr
.sin_zero
, 0, 8);
66 JackNetUnixSocket::JackNetUnixSocket(const JackNetUnixSocket
& socket
)
71 fSendAddr
= socket
.fSendAddr
;
72 fRecvAddr
= socket
.fRecvAddr
;
75 JackNetUnixSocket::~JackNetUnixSocket()
80 JackNetUnixSocket
& JackNetUnixSocket::operator=(const JackNetUnixSocket
& socket
)
82 if (this != &socket
) {
85 fSendAddr
= socket
.fSendAddr
;
86 fRecvAddr
= socket
.fRecvAddr
;
91 //socket***********************************************************************************************************
92 int JackNetUnixSocket::NewSocket()
98 fSockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
100 /* Enable address reuse */
103 if ((res
= setsockopt(fSockfd
, SOL_SOCKET
, SO_REUSEPORT
, &on
, sizeof(on
))) < 0) {
105 if ((res
= setsockopt(fSockfd
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
))) < 0) {
107 StrError(NET_ERROR_CODE
);
112 bool JackNetUnixSocket::IsLocal(char* ip
)
114 if (strcmp(ip
, "127.0.0.1") == 0) {
119 gethostname(host_name
, sizeof(host_name
));
121 struct hostent
* host
= gethostbyname(host_name
);
123 for (int i
= 0; host
->h_addr_list
[i
] != 0; ++i
) {
125 memcpy(&addr
, host
->h_addr_list
[i
], sizeof(struct in_addr
));
126 if (strcmp(inet_ntoa(addr
), ip
) == 0) {
136 int JackNetUnixSocket::Bind()
138 return bind(fSockfd
, reinterpret_cast<socket_address_t
*>(&fRecvAddr
), sizeof(socket_address_t
));
141 int JackNetUnixSocket::BindWith(const char* ip
)
143 int addr_conv
= inet_aton(ip
, &fRecvAddr
.sin_addr
);
149 int JackNetUnixSocket::BindWith(int port
)
151 fRecvAddr
.sin_port
= htons(port
);
155 int JackNetUnixSocket::Connect()
157 return connect(fSockfd
, reinterpret_cast<socket_address_t
*>(&fSendAddr
), sizeof(socket_address_t
));
160 int JackNetUnixSocket::ConnectTo(const char* ip
)
162 int addr_conv
= inet_aton(ip
, &fSendAddr
.sin_addr
);
168 void JackNetUnixSocket::Close()
175 void JackNetUnixSocket::Reset()
177 fSendAddr
.sin_family
= AF_INET
;
178 fSendAddr
.sin_port
= htons(fPort
);
179 fSendAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
180 memset(&fSendAddr
.sin_zero
, 0, 8);
181 fRecvAddr
.sin_family
= AF_INET
;
182 fRecvAddr
.sin_port
= htons(fPort
);
183 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
184 memset(&fRecvAddr
.sin_zero
, 0, 8);
187 bool JackNetUnixSocket::IsSocket()
189 return(fSockfd
) ? true : false;
192 //IP/PORT***********************************************************************************************************
193 void JackNetUnixSocket::SetPort(int port
)
196 fSendAddr
.sin_port
= htons(port
);
197 fRecvAddr
.sin_port
= htons(port
);
200 int JackNetUnixSocket::GetPort()
205 //address***********************************************************************************************************
206 int JackNetUnixSocket::SetAddress(const char* ip
, int port
)
208 int addr_conv
= inet_aton(ip
, &fSendAddr
.sin_addr
);
211 fSendAddr
.sin_port
= htons(port
);
215 char* JackNetUnixSocket::GetSendIP()
217 return inet_ntoa(fSendAddr
.sin_addr
);
220 char* JackNetUnixSocket::GetRecvIP()
222 return inet_ntoa(fRecvAddr
.sin_addr
);
225 //utility************************************************************************************************************
226 int JackNetUnixSocket::GetName(char* name
)
228 return gethostname(name
, 255);
231 int JackNetUnixSocket::JoinMCastGroup(const char* ip
)
233 struct ip_mreq multicast_req
;
234 inet_aton(ip
, &multicast_req
.imr_multiaddr
);
235 multicast_req
.imr_interface
.s_addr
= htonl(INADDR_ANY
);
236 return SetOption(IPPROTO_IP
, IP_ADD_MEMBERSHIP
, &multicast_req
, sizeof(multicast_req
));
239 //options************************************************************************************************************
240 int JackNetUnixSocket::SetOption(int level
, int optname
, const void* optval
, socklen_t optlen
)
242 return setsockopt(fSockfd
, level
, optname
, optval
, optlen
);
245 int JackNetUnixSocket::GetOption(int level
, int optname
, void* optval
, socklen_t
* optlen
)
247 return getsockopt(fSockfd
, level
, optname
, optval
, optlen
);
250 //timeout************************************************************************************************************
252 #if defined(__sun__) || defined(sun)
253 int JackNetUnixSocket::SetTimeOut(int us
)
258 if ((flags
= fcntl(fSockfd
, F_GETFL
, 0)) < 0) {
259 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_GETFL");
264 if (fcntl(fSockfd
, F_SETFL
, flags
) < 0) {
265 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_SETFL");
272 int JackNetUnixSocket::WaitRead()
280 tv
.tv_sec
= fTimeOut
/ 1000000;
281 tv
.tv_usec
= fTimeOut
% 1000000;
284 FD_SET(fSockfd
, &fdset
);
287 res
= select(fSockfd
+ 1, &fdset
, NULL
, NULL
, &tv
);
288 } while(res
< 0 && errno
== EINTR
);
292 } else if (res
== 0) {
301 int JackNetUnixSocket::WaitWrite()
309 tv
.tv_sec
= fTimeOut
/ 1000000;
310 tv
.tv_usec
= fTimeOut
% 1000000;
313 FD_SET(fSockfd
, &fdset
);
316 res
= select(fSockfd
+ 1, NULL
, &fdset
, NULL
, &tv
);
317 } while(res
< 0 && errno
== EINTR
);
321 } else if (res
== 0) {
331 int JackNetUnixSocket::SetTimeOut(int us
)
333 jack_log("JackNetUnixSocket::SetTimeout %d usecs", us
);
335 //negative timeout, or exceding 10s, return
336 if ((us
< 0) ||(us
> 10000000))
338 struct timeval timeout
;
343 timeout
.tv_usec
= us
;
346 float sec
= static_cast<float>(us
) / 1000000.f
;
347 timeout
.tv_sec
=(int) sec
;
348 float usec
= (sec
- static_cast<float>(timeout
.tv_sec
)) * 1000000;
349 timeout
.tv_usec
=(int) usec
;
351 return SetOption(SOL_SOCKET
, SO_RCVTIMEO
, &timeout
, sizeof(timeout
));
355 //local loop**********************************************************************************************************
356 int JackNetUnixSocket::SetLocalLoop()
359 return SetOption(IPPROTO_IP
, IP_MULTICAST_LOOP
, &disable
, sizeof(disable
));
362 //network operations**************************************************************************************************
363 int JackNetUnixSocket::SendTo(const void* buffer
, size_t nbytes
, int flags
)
365 #if defined(__sun__) || defined(sun)
369 return sendto(fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*>(&fSendAddr
), sizeof(socket_address_t
));
372 int JackNetUnixSocket::SendTo(const void* buffer
, size_t nbytes
, int flags
, const char* ip
)
374 int addr_conv
= inet_aton(ip
, &fSendAddr
.sin_addr
);
377 #if defined(__sun__) || defined(sun)
381 return SendTo(buffer
, nbytes
, flags
);
384 int JackNetUnixSocket::Send(const void* buffer
, size_t nbytes
, int flags
)
386 #if defined(__sun__) || defined(sun)
390 return send(fSockfd
, buffer
, nbytes
, flags
);
393 int JackNetUnixSocket::RecvFrom(void* buffer
, size_t nbytes
, int flags
)
395 socklen_t addr_len
= sizeof(socket_address_t
);
396 #if defined(__sun__) || defined(sun)
400 return recvfrom(fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*>(&fRecvAddr
), &addr_len
);
403 int JackNetUnixSocket::Recv(void* buffer
, size_t nbytes
, int flags
)
405 #if defined(__sun__) || defined(sun)
409 return recv(fSockfd
, buffer
, nbytes
, flags
);
412 int JackNetUnixSocket::CatchHost(void* buffer
, size_t nbytes
, int flags
)
414 socklen_t addr_len
= sizeof(socket_address_t
);
415 #if defined(__sun__) || defined(sun)
419 return recvfrom(fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*>(&fSendAddr
), &addr_len
);
422 net_error_t
JackNetUnixSocket::GetError()
438 return NET_CONN_ERROR
;
441 //return NET_OP_ERROR;
442 return NET_CONN_ERROR
;