11 #include "../../hal/socket.h"
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <netinet/tcp.h>
16 #include <arpa/inet.h>
19 namespace rp{
namespace net {
33 assert(!
"should not reach here");
44 reinterpret_cast<sockaddr_storage *
>(
_platform_data)->ss_family = AF_INET;
50 memcpy(
_platform_data, src._platform_data,
sizeof(sockaddr_storage));
61 reinterpret_cast<sockaddr_storage *
>(
_platform_data)->ss_family = AF_INET;
68 : _platform_data(platform_data)
71 SocketAddress & SocketAddress::operator = (
const SocketAddress &src)
73 memcpy(_platform_data, src._platform_data,
sizeof(sockaddr_storage));
78 SocketAddress::~SocketAddress()
80 delete reinterpret_cast<sockaddr_storage *
>(_platform_data);
83 SocketAddress::address_type_t SocketAddress::getAddressType()
const
85 switch(
reinterpret_cast<const sockaddr_storage *
>(_platform_data)->ss_family) {
87 return ADDRESS_TYPE_INET;
89 return ADDRESS_TYPE_INET6;
91 assert(!
"should not reach here");
92 return ADDRESS_TYPE_INET;
96 int SocketAddress::getPort()
const
98 switch (getAddressType()) {
99 case ADDRESS_TYPE_INET:
100 return (
int)ntohs(
reinterpret_cast<const sockaddr_in *
>(_platform_data)->sin_port);
101 case ADDRESS_TYPE_INET6:
102 return (
int)ntohs(
reinterpret_cast<const sockaddr_in6 *
>(_platform_data)->sin6_port);
108 u_result SocketAddress::setPort(
int port)
110 switch (getAddressType()) {
111 case ADDRESS_TYPE_INET:
112 reinterpret_cast<sockaddr_in *
>(_platform_data)->sin_port = htons((
short)port);
114 case ADDRESS_TYPE_INET6:
115 reinterpret_cast<sockaddr_in6 *
>(_platform_data)->sin6_port = htons((
short)port);
123 u_result SocketAddress::setAddressFromString(
const char * address_string, SocketAddress::address_type_t
type)
128 case ADDRESS_TYPE_INET:
129 reinterpret_cast<sockaddr_storage *
>(_platform_data)->ss_family = AF_INET;
130 ans = inet_pton(AF_INET,
132 &
reinterpret_cast<sockaddr_in *
>(_platform_data)->sin_addr);
136 case ADDRESS_TYPE_INET6:
138 reinterpret_cast<sockaddr_storage *
>(_platform_data)->ss_family = AF_INET6;
139 ans = inet_pton(AF_INET6,
141 &
reinterpret_cast<sockaddr_in6 *
>(_platform_data)->sin6_addr);
154 u_result SocketAddress::getAddressAsString(
char * buffer,
size_t buffersize)
const
156 int net_family =
reinterpret_cast<const sockaddr_storage *
>(_platform_data)->ss_family;
157 const char *ans = NULL;
158 switch (net_family) {
160 ans = inet_ntop(net_family, &
reinterpret_cast<const sockaddr_in *
>(_platform_data)->sin_addr,
165 ans = inet_ntop(net_family, &
reinterpret_cast<const sockaddr_in6 *
>(_platform_data)->sin6_addr,
175 size_t SocketAddress::LoopUpHostName(
const char * hostname,
const char * sevicename, std::vector<SocketAddress> &addresspool ,
bool performDNS, SocketAddress::address_type_t
type)
177 struct addrinfo hints;
181 memset(&hints, 0,
sizeof(
struct addrinfo));
183 hints.ai_flags = AI_PASSIVE;
186 hints.ai_family |= AI_NUMERICSERV | AI_NUMERICHOST;
190 ans = getaddrinfo(hostname, sevicename, &hints, &
result);
200 for (
struct addrinfo * cursor =
result; cursor != NULL; cursor = cursor->ai_next) {
201 if (cursor->ai_family == ADDRESS_TYPE_INET || cursor->ai_family == ADDRESS_TYPE_INET6) {
202 sockaddr_storage * storagebuffer =
new sockaddr_storage;
203 assert(
sizeof(sockaddr_storage) >= cursor->ai_addrlen);
204 memcpy(storagebuffer, cursor->ai_addr, cursor->ai_addrlen);
205 addresspool.push_back(SocketAddress(storagebuffer));
212 return addresspool.size();
216 u_result SocketAddress::getRawAddress(
_u8 * buffer,
size_t bufferSize)
const
218 switch (getAddressType()) {
219 case ADDRESS_TYPE_INET:
222 memcpy(buffer, &
reinterpret_cast<const sockaddr_in *
>(_platform_data)->sin_addr.s_addr,
sizeof(
reinterpret_cast<const sockaddr_in *
>(_platform_data)->sin_addr.s_addr));
226 case ADDRESS_TYPE_INET6:
228 memcpy(buffer,
reinterpret_cast<const sockaddr_in6 *
>(_platform_data)->sin6_addr.s6_addr,
sizeof(
reinterpret_cast<const sockaddr_in6 *
>(_platform_data)->sin6_addr.s6_addr));
238 void SocketAddress::setLoopbackAddress(SocketAddress::address_type_t
type)
243 case ADDRESS_TYPE_INET:
245 sockaddr_in * addrv4 =
reinterpret_cast<sockaddr_in *
>(_platform_data);
246 addrv4->sin_family = AF_INET;
247 addrv4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
250 case ADDRESS_TYPE_INET6:
252 sockaddr_in6 * addrv6 =
reinterpret_cast<sockaddr_in6 *
>(_platform_data);
253 addrv6->sin6_family = AF_INET6;
254 addrv6->sin6_addr = in6addr_loopback;
265 void SocketAddress::setBroadcastAddressIPv4()
269 sockaddr_in * addrv4 =
reinterpret_cast<sockaddr_in *
>(_platform_data);
270 addrv4->sin_family = AF_INET;
271 addrv4->sin_addr.s_addr = htonl(INADDR_BROADCAST);
276 void SocketAddress::setAnyAddress(SocketAddress::address_type_t
type)
280 case ADDRESS_TYPE_INET:
282 sockaddr_in * addrv4 =
reinterpret_cast<sockaddr_in *
>(_platform_data);
283 addrv4->sin_family = AF_INET;
284 addrv4->sin_addr.s_addr = htonl(INADDR_ANY);
287 case ADDRESS_TYPE_INET6:
289 sockaddr_in6 * addrv6 =
reinterpret_cast<sockaddr_in6 *
>(_platform_data);
290 addrv6->sin6_family = AF_INET6;
291 addrv6->sin6_addr = in6addr_any;
312 namespace rp {
namespace arch {
namespace net{
325 ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR , (
char *)&bool_true,
sizeof(bool_true) );
326 ::setsockopt( _socket_fd, SOL_SOCKET, SO_NOSIGPIPE, (
char*)&bool_true,
sizeof(bool_true));
329 this->setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
345 const struct sockaddr * addr =
reinterpret_cast<const struct sockaddr *
>(localaddr.
getPlatformData());
347 int ans = ::bind(_socket_fd, addr,
sizeof(sockaddr_storage));
357 struct sockaddr * addr =
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(localaddr.
getPlatformData()));
360 size_t actualsize =
sizeof(sockaddr_storage);
361 int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
363 assert(actualsize <=
sizeof(sockaddr_storage));
364 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
373 tv.tv_sec = timeout / 1000;
374 tv.tv_usec = (timeout % 1000) * 1000;
376 if (msk & SOCKET_DIR_RD) {
377 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(tv) );
381 if (msk & SOCKET_DIR_WR) {
382 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv,
sizeof(tv) );
391 const struct sockaddr * addr =
reinterpret_cast<const struct sockaddr *
>(pairAddress.
getPlatformData());
395 ans = ::connect(_socket_fd, addr,
sizeof(sockaddr_in));
397 ans = ::connect(_socket_fd, addr,
sizeof(sockaddr_in6));
419 int ans = ::listen( _socket_fd, backlog);
427 addrsize =
sizeof(sockaddr_storage);
428 int pair_socket = ::accept( _socket_fd, pairAddress?
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(pairAddress->
getPlatformData())):NULL
429 , (socklen_t*)&addrsize);
431 if (pair_socket>=0) {
440 return waitforData(timeout);
445 size_t ans = ::send( _socket_fd, buffer, len, 0);
446 if (ans == (
int)len) {
451 #if EWOULDBLOCK!=EAGAIN
465 size_t ans = ::recv( _socket_fd, buf, len, 0);
466 if (ans == (
size_t)-1) {
471 #if EWOULDBLOCK!=EAGAIN
488 virtual u_result recvNoWait(
void *buf,
size_t len,
size_t & recv_len)
490 size_t ans = ::recv( _socket_fd, buf, len, MSG_DONTWAIT);
491 if (ans == (
size_t)-1) {
493 if (errno == EAGAIN || errno == EWOULDBLOCK) {
510 struct sockaddr * addr =
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(peerAddr.
getPlatformData()));
512 size_t actualsize =
sizeof(sockaddr_storage);
513 int ans = ::getpeername(_socket_fd, addr, (socklen_t*)&actualsize);
515 assert(actualsize <=
sizeof(sockaddr_storage));
516 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
528 shutdw_opt = SHUT_RD;
531 shutdw_opt = SHUT_WR;
533 case SOCKET_DIR_BOTH:
535 shutdw_opt = SHUT_RDWR;
538 int ans = ::shutdown(_socket_fd, shutdw_opt);
544 int bool_true = enable?1:0;
550 int bool_true = enable?1:0;
558 FD_SET(_socket_fd, &wrset);
561 tv.tv_sec = timeout / 1000;
562 tv.tv_usec = (timeout % 1000) * 1000;
563 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
582 FD_SET(_socket_fd, &rdset);
585 tv.tv_sec = timeout / 1000;
586 tv.tv_usec = (timeout % 1000) * 1000;
587 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
618 ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (
char *)&bool_true,
sizeof(bool_true) );
619 setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
635 const struct sockaddr * addr =
reinterpret_cast<const struct sockaddr *
>(localaddr.
getPlatformData());
637 int ans = ::bind(_socket_fd, addr,
sizeof(sockaddr_storage));
647 struct sockaddr * addr =
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>((localaddr.
getPlatformData())));
650 size_t actualsize =
sizeof(sockaddr_storage);
651 int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
653 assert(actualsize <=
sizeof(sockaddr_storage));
654 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
663 tv.tv_sec = timeout / 1000;
664 tv.tv_usec = (timeout % 1000) * 1000;
666 if (msk & SOCKET_DIR_RD) {
667 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(tv) );
671 if (msk & SOCKET_DIR_WR) {
672 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv,
sizeof(tv) );
684 FD_SET(_socket_fd, &wrset);
687 tv.tv_sec = timeout / 1000;
688 tv.tv_usec = (timeout % 1000) * 1000;
689 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
708 FD_SET(_socket_fd, &rdset);
711 tv.tv_sec = timeout / 1000;
712 tv.tv_usec = (timeout % 1000) * 1000;
713 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
730 const struct sockaddr * addr = target ?
reinterpret_cast<const struct sockaddr *
>(target->
getPlatformData()) : NULL;
731 int dest_addr_size = (target ?
sizeof(sockaddr_storage) : 0);
732 int ans = ::sendto(_socket_fd, (
const char *)buffer, (
int)len, 0, addr, dest_addr_size);
734 assert(ans == (
int)len);
739 #if EWOULDBLOCK!=EAGAIN
755 sockaddr_storage unspecAddr;
756 unspecAddr.ss_family = AF_UNSPEC;
758 const struct sockaddr* addr = pairAddress ?
reinterpret_cast<const struct sockaddr*
>(pairAddress->
getPlatformData()) :
reinterpret_cast<const struct sockaddr*
>(&unspecAddr);
761 ans = ::connect(_socket_fd, addr,
sizeof(sockaddr_in));
763 ans = ::connect(_socket_fd, addr,
sizeof(sockaddr_in6));
776 FD_SET(_socket_fd, &rdset);
780 memset(recv_data, 0,
sizeof(recv_data));
782 res = select(FD_SETSIZE, &rdset,
nullptr,
nullptr, &tv);
784 recv(_socket_fd, recv_data, 1, 0);
791 struct sockaddr * addr = (sourceAddr?
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(sourceAddr->
getPlatformData())):NULL);
792 size_t source_addr_size = (sourceAddr?
sizeof(sockaddr_storage):0);
794 size_t ans = ::recvfrom( _socket_fd, buf, len, 0, addr, (socklen_t*)&source_addr_size);
795 if (ans == (
size_t)-1) {
799 #if EWOULDBLOCK!=EAGAIN
815 virtual u_result recvFromNoWait(
void *buf,
size_t len,
size_t & recv_len,
SocketAddress * sourceAddr)
817 struct sockaddr * addr = (sourceAddr?
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(sourceAddr->
getPlatformData())):NULL);
818 size_t source_addr_size = (sourceAddr?
sizeof(sockaddr_storage):0);
821 size_t ans = ::recvfrom( _socket_fd, buf, len, MSG_DONTWAIT, addr, &source_addr_size);
823 if (ans == (
size_t)-1) {
825 if (errno == EAGAIN || errno == EWOULDBLOCK) {
849 namespace rp {
namespace net{
860 assert(!
"should not reach here, AF_PACKET is not supported on macOS");
863 assert(!
"should not reach here");
875 int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
876 if (socket_fd == -1)
return NULL;
889 int socket_fd = ::socket(socket_family, (family==
SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
890 if (socket_fd == -1)
return NULL;