00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "sdkcommon.h"
00011 #include "../../hal/socket.h"
00012
00013 #include <sys/socket.h>
00014 #include <netinet/in.h>
00015 #include <netinet/tcp.h>
00016 #include <arpa/inet.h>
00017 #include <netdb.h>
00018
00019 namespace rp{ namespace net {
00020
00021
00022 static inline int _halAddrTypeToOSType(SocketAddress::address_type_t type)
00023 {
00024 switch (type) {
00025 case SocketAddress::ADDRESS_TYPE_INET:
00026 return AF_INET;
00027 case SocketAddress::ADDRESS_TYPE_INET6:
00028 return AF_INET6;
00029 case SocketAddress::ADDRESS_TYPE_UNSPEC:
00030 return AF_UNSPEC;
00031
00032 default:
00033 assert(!"should not reach here");
00034 return AF_UNSPEC;
00035 }
00036 }
00037
00038
00039 SocketAddress::SocketAddress()
00040 {
00041 _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00042 memset(_platform_data, 0, sizeof(sockaddr_storage));
00043
00044 reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00045 }
00046
00047 SocketAddress::SocketAddress(const SocketAddress & src)
00048 {
00049 _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00050 memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
00051 }
00052
00053
00054
00055 SocketAddress::SocketAddress(const char * addrString, int port, SocketAddress::address_type_t type)
00056 {
00057 _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00058 memset(_platform_data, 0, sizeof(sockaddr_storage));
00059
00060
00061 reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00062
00063 setAddressFromString(addrString, type);
00064 setPort(port);
00065 }
00066
00067 SocketAddress::SocketAddress(void * platform_data)
00068 : _platform_data(platform_data)
00069 {}
00070
00071 SocketAddress & SocketAddress::operator = (const SocketAddress &src)
00072 {
00073 memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
00074 return *this;
00075 }
00076
00077
00078 SocketAddress::~SocketAddress()
00079 {
00080 delete reinterpret_cast<sockaddr_storage *>(_platform_data);
00081 }
00082
00083 SocketAddress::address_type_t SocketAddress::getAddressType() const
00084 {
00085 switch(reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family) {
00086 case AF_INET:
00087 return ADDRESS_TYPE_INET;
00088 case AF_INET6:
00089 return ADDRESS_TYPE_INET6;
00090 default:
00091 assert(!"should not reach here");
00092 return ADDRESS_TYPE_INET;
00093 }
00094 }
00095
00096 int SocketAddress::getPort() const
00097 {
00098 switch (getAddressType()) {
00099 case ADDRESS_TYPE_INET:
00100 return (int)ntohs(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_port);
00101 case ADDRESS_TYPE_INET6:
00102 return (int)ntohs(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_port);
00103 default:
00104 return 0;
00105 }
00106 }
00107
00108 u_result SocketAddress::setPort(int port)
00109 {
00110 switch (getAddressType()) {
00111 case ADDRESS_TYPE_INET:
00112 reinterpret_cast<sockaddr_in *>(_platform_data)->sin_port = htons((short)port);
00113 break;
00114 case ADDRESS_TYPE_INET6:
00115 reinterpret_cast<sockaddr_in6 *>(_platform_data)->sin6_port = htons((short)port);
00116 break;
00117 default:
00118 return RESULT_OPERATION_FAIL;
00119 }
00120 return RESULT_OK;
00121 }
00122
00123 u_result SocketAddress::setAddressFromString(const char * address_string, SocketAddress::address_type_t type)
00124 {
00125 int ans = 0;
00126 int prevPort = getPort();
00127 switch (type) {
00128 case ADDRESS_TYPE_INET:
00129 reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00130 ans = inet_pton(AF_INET,
00131 address_string,
00132 &reinterpret_cast<sockaddr_in *>(_platform_data)->sin_addr);
00133 break;
00134
00135
00136 case ADDRESS_TYPE_INET6:
00137
00138 reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET6;
00139 ans = inet_pton(AF_INET6,
00140 address_string,
00141 &reinterpret_cast<sockaddr_in6 *>(_platform_data)->sin6_addr);
00142 break;
00143
00144 default:
00145 return RESULT_INVALID_DATA;
00146
00147 }
00148 setPort(prevPort);
00149
00150 return ans<=0?RESULT_INVALID_DATA:RESULT_OK;
00151 }
00152
00153
00154 u_result SocketAddress::getAddressAsString(char * buffer, size_t buffersize) const
00155 {
00156 int net_family = reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family;
00157 const char *ans = NULL;
00158 switch (net_family) {
00159 case AF_INET:
00160 ans = inet_ntop(net_family, &reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr,
00161 buffer, buffersize);
00162 break;
00163
00164 case AF_INET6:
00165 ans = inet_ntop(net_family, &reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr,
00166 buffer, buffersize);
00167
00168 break;
00169 }
00170 return !ans?RESULT_OPERATION_FAIL:RESULT_OK;
00171 }
00172
00173
00174
00175 size_t SocketAddress::LoopUpHostName(const char * hostname, const char * sevicename, std::vector<SocketAddress> &addresspool , bool performDNS, SocketAddress::address_type_t type)
00176 {
00177 struct addrinfo hints;
00178 struct addrinfo *result;
00179 int ans;
00180
00181 memset(&hints, 0, sizeof(struct addrinfo));
00182 hints.ai_family = _halAddrTypeToOSType(type);
00183 hints.ai_flags = AI_PASSIVE;
00184
00185 if (!performDNS) {
00186 hints.ai_family |= AI_NUMERICSERV | AI_NUMERICHOST;
00187
00188 }
00189
00190 ans = getaddrinfo(hostname, sevicename, &hints, &result);
00191
00192 addresspool.clear();
00193
00194 if (ans != 0) {
00195
00196 return 0;
00197 }
00198
00199
00200 for (struct addrinfo * cursor = result; cursor != NULL; cursor = cursor->ai_next) {
00201 if (cursor->ai_family == ADDRESS_TYPE_INET || cursor->ai_family == ADDRESS_TYPE_INET6) {
00202 sockaddr_storage * storagebuffer = new sockaddr_storage;
00203 assert(sizeof(sockaddr_storage) >= cursor->ai_addrlen);
00204 memcpy(storagebuffer, cursor->ai_addr, cursor->ai_addrlen);
00205 addresspool.push_back(SocketAddress(storagebuffer));
00206 }
00207 }
00208
00209
00210 freeaddrinfo(result);
00211
00212 return addresspool.size();
00213 }
00214
00215
00216 u_result SocketAddress::getRawAddress(_u8 * buffer, size_t bufferSize) const
00217 {
00218 switch (getAddressType()) {
00219 case ADDRESS_TYPE_INET:
00220 if (bufferSize < sizeof(in_addr_t)) return RESULT_INSUFFICIENT_MEMORY;
00221
00222 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));
00223
00224
00225 break;
00226 case ADDRESS_TYPE_INET6:
00227 if (bufferSize < sizeof(in6_addr)) return RESULT_INSUFFICIENT_MEMORY;
00228 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));
00229
00230 break;
00231 default:
00232 return RESULT_OPERATION_FAIL;
00233 }
00234 return RESULT_OK;
00235 }
00236
00237
00238 void SocketAddress::setLoopbackAddress(SocketAddress::address_type_t type)
00239 {
00240
00241 int prevPort = getPort();
00242 switch (type) {
00243 case ADDRESS_TYPE_INET:
00244 {
00245 sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00246 addrv4->sin_family = AF_INET;
00247 addrv4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
00248 }
00249 break;
00250 case ADDRESS_TYPE_INET6:
00251 {
00252 sockaddr_in6 * addrv6 = reinterpret_cast<sockaddr_in6 *>(_platform_data);
00253 addrv6->sin6_family = AF_INET6;
00254 addrv6->sin6_addr = in6addr_loopback;
00255
00256 }
00257 break;
00258 default:
00259 return;
00260 }
00261
00262 setPort(prevPort);
00263 }
00264
00265 void SocketAddress::setBroadcastAddressIPv4()
00266 {
00267
00268 int prevPort = getPort();
00269 sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00270 addrv4->sin_family = AF_INET;
00271 addrv4->sin_addr.s_addr = htonl(INADDR_BROADCAST);
00272 setPort(prevPort);
00273
00274 }
00275
00276 void SocketAddress::setAnyAddress(SocketAddress::address_type_t type)
00277 {
00278 int prevPort = getPort();
00279 switch (type) {
00280 case ADDRESS_TYPE_INET:
00281 {
00282 sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00283 addrv4->sin_family = AF_INET;
00284 addrv4->sin_addr.s_addr = htonl(INADDR_ANY);
00285 }
00286 break;
00287 case ADDRESS_TYPE_INET6:
00288 {
00289 sockaddr_in6 * addrv6 = reinterpret_cast<sockaddr_in6 *>(_platform_data);
00290 addrv6->sin6_family = AF_INET6;
00291 addrv6->sin6_addr = in6addr_any;
00292
00293 }
00294 break;
00295 default:
00296 return;
00297 }
00298
00299 setPort(prevPort);
00300
00301
00302 }
00303
00304
00305 }}
00306
00307
00308
00310
00311
00312 namespace rp { namespace arch { namespace net{
00313
00314 using namespace rp::net;
00315
00316 class _single_thread StreamSocketImpl : public StreamSocket
00317 {
00318 public:
00319
00320 StreamSocketImpl(int fd)
00321 : _socket_fd(fd)
00322 {
00323 assert(fd>=0);
00324 int bool_true = 1;
00325 ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR , (char *)&bool_true, sizeof(bool_true) );
00326 ::setsockopt( _socket_fd, SOL_SOCKET, SO_NOSIGPIPE, (char*)&bool_true, sizeof(bool_true));
00327
00328 enableNoDelay(true);
00329 this->setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00330 }
00331
00332 virtual ~StreamSocketImpl()
00333 {
00334 close(_socket_fd);
00335 }
00336
00337 virtual void dispose()
00338 {
00339 delete this;
00340 }
00341
00342
00343 virtual u_result bind(const SocketAddress & localaddr)
00344 {
00345 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00346 assert(addr);
00347 int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00348 if (ans) {
00349 return RESULT_OPERATION_FAIL;
00350 } else {
00351 return RESULT_OK;
00352 }
00353 }
00354
00355 virtual u_result getLocalAddress(SocketAddress & localaddr)
00356 {
00357 struct sockaddr * addr = reinterpret_cast<struct sockaddr *>( const_cast<void *>(localaddr.getPlatformData()));
00358 assert(addr);
00359
00360 size_t actualsize = sizeof(sockaddr_storage);
00361 int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00362
00363 assert(actualsize <= sizeof(sockaddr_storage));
00364 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00365
00366 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00367 }
00368
00369 virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00370 {
00371 int ans;
00372 timeval tv;
00373 tv.tv_sec = timeout / 1000;
00374 tv.tv_usec = (timeout % 1000) * 1000;
00375
00376 if (msk & SOCKET_DIR_RD) {
00377 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00378 if (ans) return RESULT_OPERATION_FAIL;
00379 }
00380
00381 if (msk & SOCKET_DIR_WR) {
00382 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00383 if (ans) return RESULT_OPERATION_FAIL;
00384 }
00385
00386 return RESULT_OK;
00387 }
00388
00389 virtual u_result connect(const SocketAddress & pairAddress)
00390 {
00391 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(pairAddress.getPlatformData());
00392 int ans = ::connect(_socket_fd, addr, sizeof(sockaddr_storage));
00393 if (!ans) return RESULT_OK;
00394
00395
00396 switch (errno) {
00397 case EAFNOSUPPORT:
00398 return RESULT_OPERATION_NOT_SUPPORT;
00399 #if 0
00400 case EINPROGRESS:
00401 return RESULT_OK;
00402 #endif
00403 case ETIMEDOUT:
00404 return RESULT_OPERATION_TIMEOUT;
00405 default:
00406 return RESULT_OPERATION_FAIL;
00407 }
00408 }
00409
00410 virtual u_result listen(int backlog)
00411 {
00412 int ans = ::listen( _socket_fd, backlog);
00413
00414 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00415 }
00416
00417 virtual StreamSocket * accept(SocketAddress * pairAddress)
00418 {
00419 size_t addrsize;
00420 addrsize = sizeof(sockaddr_storage);
00421 int pair_socket = ::accept( _socket_fd, pairAddress?reinterpret_cast<struct sockaddr *>(const_cast<void *>(pairAddress->getPlatformData())):NULL
00422 , (socklen_t*)&addrsize);
00423
00424 if (pair_socket>=0) {
00425 return new StreamSocketImpl(pair_socket);
00426 } else {
00427 return NULL;
00428 }
00429 }
00430
00431 virtual u_result waitforIncomingConnection(_u32 timeout)
00432 {
00433 return waitforData(timeout);
00434 }
00435
00436 virtual u_result send(const void * buffer, size_t len)
00437 {
00438 size_t ans = ::send( _socket_fd, buffer, len, 0);
00439 if (ans == (int)len) {
00440 return RESULT_OK;
00441 } else {
00442 switch (errno) {
00443 case EAGAIN:
00444 #if EWOULDBLOCK!=EAGAIN
00445 case EWOULDBLOCK:
00446 #endif
00447 return RESULT_OPERATION_TIMEOUT;
00448 default:
00449 return RESULT_OPERATION_FAIL;
00450 }
00451 }
00452
00453 }
00454
00455
00456 virtual u_result recv(void *buf, size_t len, size_t & recv_len)
00457 {
00458 size_t ans = ::recv( _socket_fd, buf, len, 0);
00459 if (ans == (size_t)-1) {
00460 recv_len = 0;
00461
00462 switch (errno) {
00463 case EAGAIN:
00464 #if EWOULDBLOCK!=EAGAIN
00465 case EWOULDBLOCK:
00466 #endif
00467 return RESULT_OPERATION_TIMEOUT;
00468 default:
00469 return RESULT_OPERATION_FAIL;
00470 }
00471
00472
00473
00474 } else {
00475 recv_len = ans;
00476 return RESULT_OK;
00477 }
00478 }
00479
00480 #if 0
00481 virtual u_result recvNoWait(void *buf, size_t len, size_t & recv_len)
00482 {
00483 size_t ans = ::recv( _socket_fd, buf, len, MSG_DONTWAIT);
00484 if (ans == (size_t)-1) {
00485 recv_len = 0;
00486 if (errno == EAGAIN || errno == EWOULDBLOCK) {
00487 return RESULT_OK;
00488 } else {
00489 return RESULT_OPERATION_FAIL;
00490 }
00491
00492
00493 } else {
00494 recv_len = ans;
00495 return RESULT_OK;
00496 }
00497
00498 }
00499 #endif
00500
00501 virtual u_result getPeerAddress(SocketAddress & peerAddr)
00502 {
00503 struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>(peerAddr.getPlatformData()));
00504 assert(addr);
00505 size_t actualsize = sizeof(sockaddr_storage);
00506 int ans = ::getpeername(_socket_fd, addr, (socklen_t*)&actualsize);
00507
00508 assert(actualsize <= sizeof(sockaddr_storage));
00509 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00510
00511 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00512
00513 }
00514
00515 virtual u_result shutdown(socket_direction_mask mask)
00516 {
00517 int shutdw_opt ;
00518
00519 switch (mask) {
00520 case SOCKET_DIR_RD:
00521 shutdw_opt = SHUT_RD;
00522 break;
00523 case SOCKET_DIR_WR:
00524 shutdw_opt = SHUT_WR;
00525 break;
00526 case SOCKET_DIR_BOTH:
00527 default:
00528 shutdw_opt = SHUT_RDWR;
00529 }
00530
00531 int ans = ::shutdown(_socket_fd, shutdw_opt);
00532 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00533 }
00534
00535 virtual u_result enableKeepAlive(bool enable)
00536 {
00537 int bool_true = enable?1:0;
00538 return ::setsockopt( _socket_fd, SOL_SOCKET, SO_KEEPALIVE , &bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00539 }
00540
00541 virtual u_result enableNoDelay(bool enable )
00542 {
00543 int bool_true = enable?1:0;
00544 return ::setsockopt( _socket_fd, IPPROTO_TCP, TCP_NODELAY,&bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00545 }
00546
00547 virtual u_result waitforSent(_u32 timeout )
00548 {
00549 fd_set wrset;
00550 FD_ZERO(&wrset);
00551 FD_SET(_socket_fd, &wrset);
00552
00553 timeval tv;
00554 tv.tv_sec = timeout / 1000;
00555 tv.tv_usec = (timeout % 1000) * 1000;
00556 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00557
00558 switch (ans) {
00559 case 1:
00560
00561 return RESULT_OK;
00562 case 0:
00563
00564 return RESULT_OPERATION_TIMEOUT;
00565 default:
00566 delay(0);
00567 return RESULT_OPERATION_FAIL;
00568 }
00569 }
00570
00571 virtual u_result waitforData(_u32 timeout )
00572 {
00573 fd_set rdset;
00574 FD_ZERO(&rdset);
00575 FD_SET(_socket_fd, &rdset);
00576
00577 timeval tv;
00578 tv.tv_sec = timeout / 1000;
00579 tv.tv_usec = (timeout % 1000) * 1000;
00580 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00581
00582 switch (ans) {
00583 case 1:
00584
00585 return RESULT_OK;
00586 case 0:
00587
00588 return RESULT_OPERATION_TIMEOUT;
00589 default:
00590 delay(0);
00591 return RESULT_OPERATION_FAIL;
00592 }
00593 }
00594
00595 protected:
00596 int _socket_fd;
00597
00598
00599 };
00600
00601
00602 class _single_thread DGramSocketImpl : public DGramSocket
00603 {
00604 public:
00605
00606 DGramSocketImpl(int fd)
00607 : _socket_fd(fd)
00608 {
00609 assert(fd>=0);
00610 int bool_true = 1;
00611 ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (char *)&bool_true, sizeof(bool_true) );
00612 setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00613 }
00614
00615 virtual ~DGramSocketImpl()
00616 {
00617 close(_socket_fd);
00618 }
00619
00620 virtual void dispose()
00621 {
00622 delete this;
00623 }
00624
00625
00626 virtual u_result bind(const SocketAddress & localaddr)
00627 {
00628 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00629 assert(addr);
00630 int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00631 if (ans) {
00632 return RESULT_OPERATION_FAIL;
00633 } else {
00634 return RESULT_OK;
00635 }
00636 }
00637
00638 virtual u_result getLocalAddress(SocketAddress & localaddr)
00639 {
00640 struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>((localaddr.getPlatformData())));
00641 assert(addr);
00642
00643 size_t actualsize = sizeof(sockaddr_storage);
00644 int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00645
00646 assert(actualsize <= sizeof(sockaddr_storage));
00647 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00648
00649 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00650 }
00651
00652 virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00653 {
00654 int ans;
00655 timeval tv;
00656 tv.tv_sec = timeout / 1000;
00657 tv.tv_usec = (timeout % 1000) * 1000;
00658
00659 if (msk & SOCKET_DIR_RD) {
00660 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00661 if (ans) return RESULT_OPERATION_FAIL;
00662 }
00663
00664 if (msk & SOCKET_DIR_WR) {
00665 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00666 if (ans) return RESULT_OPERATION_FAIL;
00667 }
00668
00669 return RESULT_OK;
00670 }
00671
00672
00673 virtual u_result waitforSent(_u32 timeout )
00674 {
00675 fd_set wrset;
00676 FD_ZERO(&wrset);
00677 FD_SET(_socket_fd, &wrset);
00678
00679 timeval tv;
00680 tv.tv_sec = timeout / 1000;
00681 tv.tv_usec = (timeout % 1000) * 1000;
00682 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00683
00684 switch (ans) {
00685 case 1:
00686
00687 return RESULT_OK;
00688 case 0:
00689
00690 return RESULT_OPERATION_TIMEOUT;
00691 default:
00692 delay(0);
00693 return RESULT_OPERATION_FAIL;
00694 }
00695 }
00696
00697 virtual u_result waitforData(_u32 timeout )
00698 {
00699 fd_set rdset;
00700 FD_ZERO(&rdset);
00701 FD_SET(_socket_fd, &rdset);
00702
00703 timeval tv;
00704 tv.tv_sec = timeout / 1000;
00705 tv.tv_usec = (timeout % 1000) * 1000;
00706 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00707
00708 switch (ans) {
00709 case 1:
00710
00711 return RESULT_OK;
00712 case 0:
00713
00714 return RESULT_OPERATION_TIMEOUT;
00715 default:
00716 delay(0);
00717 return RESULT_OPERATION_FAIL;
00718 }
00719 }
00720
00721 virtual u_result sendTo(const SocketAddress & target, const void * buffer, size_t len)
00722 {
00723 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(target.getPlatformData());
00724 assert(addr);
00725 size_t ans = ::sendto( _socket_fd, buffer, len, 0, addr, sizeof(sockaddr_storage));
00726 if (ans != (size_t)-1) {
00727 assert(ans == (int)len);
00728 return RESULT_OK;
00729 } else {
00730 switch (errno) {
00731 case EAGAIN:
00732 #if EWOULDBLOCK!=EAGAIN
00733 case EWOULDBLOCK:
00734 #endif
00735 return RESULT_OPERATION_TIMEOUT;
00736
00737 case EMSGSIZE:
00738 return RESULT_INVALID_DATA;
00739 default:
00740 return RESULT_OPERATION_FAIL;
00741 }
00742
00743 }
00744
00745 }
00746
00747
00748 virtual u_result recvFrom(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00749 {
00750 struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00751 size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00752
00753 size_t ans = ::recvfrom( _socket_fd, buf, len, 0, addr, (socklen_t*)&source_addr_size);
00754 if (ans == (size_t)-1) {
00755 recv_len = 0;
00756 switch (errno) {
00757 case EAGAIN:
00758 #if EWOULDBLOCK!=EAGAIN
00759 case EWOULDBLOCK:
00760 #endif
00761 return RESULT_OPERATION_TIMEOUT;
00762 default:
00763 return RESULT_OPERATION_FAIL;
00764 }
00765
00766 } else {
00767 recv_len = ans;
00768 return RESULT_OK;
00769 }
00770
00771 }
00772
00773 #if 0
00774 virtual u_result recvFromNoWait(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00775 {
00776 struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00777 size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00778
00779
00780 size_t ans = ::recvfrom( _socket_fd, buf, len, MSG_DONTWAIT, addr, &source_addr_size);
00781
00782 if (ans == (size_t)-1) {
00783 recv_len = 0;
00784 if (errno == EAGAIN || errno == EWOULDBLOCK) {
00785 return RESULT_OK;
00786 } else {
00787 return RESULT_OPERATION_FAIL;
00788 }
00789
00790
00791 } else {
00792 recv_len = ans;
00793 return RESULT_OK;
00794 }
00795
00796 }
00797 #endif
00798
00799 protected:
00800 int _socket_fd;
00801
00802 };
00803
00804
00805 }}}
00806
00807
00808 namespace rp { namespace net{
00809
00810
00811 static inline int _socketHalFamilyToOSFamily(SocketBase::socket_family_t family)
00812 {
00813 switch (family) {
00814 case SocketBase::SOCKET_FAMILY_INET:
00815 return AF_INET;
00816 case SocketBase::SOCKET_FAMILY_INET6:
00817 return AF_INET6;
00818 case SocketBase::SOCKET_FAMILY_RAW:
00819 assert(!"should not reach here, AF_PACKET is not supported on macOS");
00820 return AF_INET;
00821 default:
00822 assert(!"should not reach here");
00823 return AF_INET;
00824 }
00825
00826 }
00827
00828 StreamSocket * StreamSocket::CreateSocket(SocketBase::socket_family_t family)
00829 {
00830 if (family == SOCKET_FAMILY_RAW) return NULL;
00831
00832
00833 int socket_family = _socketHalFamilyToOSFamily(family);
00834 int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
00835 if (socket_fd == -1) return NULL;
00836
00837 StreamSocket * newborn = static_cast<StreamSocket *>(new rp::arch::net::StreamSocketImpl(socket_fd));
00838 return newborn;
00839
00840 }
00841
00842
00843 DGramSocket * DGramSocket::CreateSocket(SocketBase::socket_family_t family)
00844 {
00845 int socket_family = _socketHalFamilyToOSFamily(family);
00846
00847
00848 int socket_fd = ::socket(socket_family, (family==SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
00849 if (socket_fd == -1) return NULL;
00850
00851 DGramSocket * newborn = static_cast<DGramSocket *>(new rp::arch::net::DGramSocketImpl(socket_fd));
00852 return newborn;
00853
00854 }
00855
00856
00857 }}
00858