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;
61 reinterpret_cast<sockaddr_storage *
>(
_platform_data)->ss_family = AF_INET;
85 switch(reinterpret_cast<const sockaddr_storage *>(
_platform_data)->ss_family) {
91 assert(!
"should not reach here");
100 return (
int)ntohs(reinterpret_cast<const sockaddr_in *>(
_platform_data)->sin_port);
102 return (
int)ntohs(reinterpret_cast<const sockaddr_in6 *>(
_platform_data)->sin6_port);
112 reinterpret_cast<sockaddr_in *
>(
_platform_data)->sin_port = htons((
short)port);
115 reinterpret_cast<sockaddr_in6 *
>(
_platform_data)->sin6_port = htons((
short)port);
129 reinterpret_cast<sockaddr_storage *
>(
_platform_data)->ss_family = AF_INET;
130 ans = inet_pton(AF_INET,
138 reinterpret_cast<sockaddr_storage *
>(
_platform_data)->ss_family = AF_INET6;
139 ans = inet_pton(AF_INET6,
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,
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) {
202 sockaddr_storage * storagebuffer =
new sockaddr_storage;
203 assert(
sizeof(sockaddr_storage) >= cursor->ai_addrlen);
204 memcpy(storagebuffer, cursor->ai_addr, cursor->ai_addrlen);
210 freeaddrinfo(result);
212 return addresspool.size();
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));
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));
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);
252 sockaddr_in6 * addrv6 =
reinterpret_cast<sockaddr_in6 *
>(
_platform_data);
253 addrv6->sin6_family = AF_INET6;
254 addrv6->sin6_addr = in6addr_loopback;
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);
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);
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());
392 int ans = ::connect(_socket_fd, addr,
sizeof(sockaddr_storage));
412 int ans = ::listen( _socket_fd, backlog);
420 addrsize =
sizeof(sockaddr_storage);
421 int pair_socket = ::accept( _socket_fd, pairAddress?reinterpret_cast<struct sockaddr *>(const_cast<void *>(pairAddress->
getPlatformData())):NULL
422 , (socklen_t*)&addrsize);
424 if (pair_socket>=0) {
425 return new StreamSocketImpl(pair_socket);
433 return waitforData(timeout);
438 size_t ans = ::send( _socket_fd, buffer, len, 0);
439 if (ans == (
int)len) {
444 #if EWOULDBLOCK!=EAGAIN 458 size_t ans = ::recv( _socket_fd, buf, len, 0);
459 if (ans == (
size_t)-1) {
464 #if EWOULDBLOCK!=EAGAIN 481 virtual u_result recvNoWait(
void *buf,
size_t len,
size_t & recv_len)
483 size_t ans = ::recv( _socket_fd, buf, len, MSG_DONTWAIT);
484 if (ans == (
size_t)-1) {
486 if (errno == EAGAIN || errno == EWOULDBLOCK) {
503 struct sockaddr * addr =
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(peerAddr.
getPlatformData()));
505 size_t actualsize =
sizeof(sockaddr_storage);
506 int ans = ::getpeername(_socket_fd, addr, (socklen_t*)&actualsize);
508 assert(actualsize <=
sizeof(sockaddr_storage));
509 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
521 shutdw_opt = SHUT_RD;
524 shutdw_opt = SHUT_WR;
526 case SOCKET_DIR_BOTH:
528 shutdw_opt = SHUT_RDWR;
531 int ans = ::shutdown(_socket_fd, shutdw_opt);
537 int bool_true = enable?1:0;
543 int bool_true = enable?1:0;
551 FD_SET(_socket_fd, &wrset);
554 tv.tv_sec = timeout / 1000;
555 tv.tv_usec = (timeout % 1000) * 1000;
556 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
575 FD_SET(_socket_fd, &rdset);
578 tv.tv_sec = timeout / 1000;
579 tv.tv_usec = (timeout % 1000) * 1000;
580 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
611 ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (
char *)&bool_true,
sizeof(bool_true) );
612 setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
628 const struct sockaddr * addr =
reinterpret_cast<const struct sockaddr *
>(localaddr.
getPlatformData());
630 int ans = ::bind(_socket_fd, addr,
sizeof(sockaddr_storage));
640 struct sockaddr * addr =
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>((localaddr.
getPlatformData())));
643 size_t actualsize =
sizeof(sockaddr_storage);
644 int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
646 assert(actualsize <=
sizeof(sockaddr_storage));
647 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
656 tv.tv_sec = timeout / 1000;
657 tv.tv_usec = (timeout % 1000) * 1000;
659 if (msk & SOCKET_DIR_RD) {
660 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(tv) );
664 if (msk & SOCKET_DIR_WR) {
665 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv,
sizeof(tv) );
677 FD_SET(_socket_fd, &wrset);
680 tv.tv_sec = timeout / 1000;
681 tv.tv_usec = (timeout % 1000) * 1000;
682 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
701 FD_SET(_socket_fd, &rdset);
704 tv.tv_sec = timeout / 1000;
705 tv.tv_usec = (timeout % 1000) * 1000;
706 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
723 const struct sockaddr * addr =
reinterpret_cast<const struct sockaddr *
>(target.
getPlatformData());
725 size_t ans = ::sendto( _socket_fd, buffer, len, 0, addr,
sizeof(sockaddr_storage));
726 if (ans != (
size_t)-1) {
727 assert(ans == (
int)len);
732 #if EWOULDBLOCK!=EAGAIN 750 struct sockaddr * addr = (sourceAddr?
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(sourceAddr->
getPlatformData())):NULL);
751 size_t source_addr_size = (sourceAddr?
sizeof(sockaddr_storage):0);
753 size_t ans = ::recvfrom( _socket_fd, buf, len, 0, addr, (socklen_t*)&source_addr_size);
754 if (ans == (
size_t)-1) {
758 #if EWOULDBLOCK!=EAGAIN 774 virtual u_result recvFromNoWait(
void *buf,
size_t len,
size_t & recv_len,
SocketAddress * sourceAddr)
776 struct sockaddr * addr = (sourceAddr?
reinterpret_cast<struct sockaddr *
>(
const_cast<void *
>(sourceAddr->
getPlatformData())):NULL);
777 size_t source_addr_size = (sourceAddr?
sizeof(sockaddr_storage):0);
780 size_t ans = ::recvfrom( _socket_fd, buf, len, MSG_DONTWAIT, addr, &source_addr_size);
782 if (ans == (
size_t)-1) {
784 if (errno == EAGAIN || errno == EWOULDBLOCK) {
808 namespace rp {
namespace net{
819 assert(!
"should not reach here, AF_PACKET is not supported on macOS");
822 assert(!
"should not reach here");
830 if (family == SOCKET_FAMILY_RAW)
return NULL;
834 int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
835 if (socket_fd == -1)
return NULL;
848 int socket_fd = ::socket(socket_family, (family==SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
849 if (socket_fd == -1)
return NULL;
virtual StreamSocket * accept(SocketAddress *pairAddress)
static int _socketHalFamilyToOSFamily(SocketBase::socket_family_t family)
virtual void setAnyAddress(address_type_t=ADDRESS_TYPE_INET)
virtual u_result setPort(int port)
virtual void setLoopbackAddress(address_type_t=ADDRESS_TYPE_INET)
virtual u_result connect(const SocketAddress &pairAddress)
virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
static int _halAddrTypeToOSType(SocketAddress::address_type_t type)
virtual void setBroadcastAddressIPv4()
virtual u_result recvFrom(void *buf, size_t len, size_t &recv_len, SocketAddress *sourceAddr)
SocketAddress & operator=(const SocketAddress &)
virtual u_result recv(void *buf, size_t len, size_t &recv_len)
virtual ~StreamSocketImpl()
virtual u_result getAddressAsString(char *buffer, size_t buffersize) const
virtual u_result waitforData(_u32 timeout)
#define RESULT_INSUFFICIENT_MEMORY
static size_t LoopUpHostName(const char *hostname, const char *sevicename, std::vector< SocketAddress > &addresspool, bool performDNS=true, address_type_t=ADDRESS_TYPE_INET)
virtual u_result enableKeepAlive(bool enable)
virtual u_result waitforSent(_u32 timeout)
virtual ~DGramSocketImpl()
virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
virtual u_result setAddressFromString(const char *address_string, address_type_t=ADDRESS_TYPE_INET)
const void * getPlatformData() const
virtual u_result waitforSent(_u32 timeout)
virtual u_result sendTo(const SocketAddress &target, const void *buffer, size_t len)
virtual u_result getLocalAddress(SocketAddress &localaddr)
virtual u_result listen(int backlog)
virtual u_result bind(const SocketAddress &localaddr)
static StreamSocket * CreateSocket(socket_family_t family=SOCKET_FAMILY_INET)
#define RESULT_OPERATION_TIMEOUT
virtual u_result getLocalAddress(SocketAddress &localaddr)
virtual u_result send(const void *buffer, size_t len)
virtual u_result waitforData(_u32 timeout)
virtual address_type_t getAddressType() const
virtual u_result enableNoDelay(bool enable)
virtual u_result getPeerAddress(SocketAddress &peerAddr)
virtual u_result shutdown(socket_direction_mask mask)
#define RESULT_OPERATION_NOT_SUPPORT
virtual u_result bind(const SocketAddress &localaddr)
#define RESULT_OPERATION_FAIL
virtual u_result getRawAddress(_u8 *buffer, size_t bufferSize) const
virtual int getPort() const
#define RESULT_INVALID_DATA
static DGramSocket * CreateSocket(socket_family_t family=SOCKET_FAMILY_INET)
virtual u_result waitforIncomingConnection(_u32 timeout)