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<=0?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::s_addr)) 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::s6_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
00327 enableNoDelay(true);
00328 this->setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00329 }
00330
00331 virtual ~StreamSocketImpl()
00332 {
00333 close(_socket_fd);
00334 }
00335
00336 virtual void dispose()
00337 {
00338 delete this;
00339 }
00340
00341
00342 virtual u_result bind(const SocketAddress & localaddr)
00343 {
00344 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00345 assert(addr);
00346 int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00347 if (ans) {
00348 return RESULT_OPERATION_FAIL;
00349 } else {
00350 return RESULT_OK;
00351 }
00352 }
00353
00354 virtual u_result getLocalAddress(SocketAddress & localaddr)
00355 {
00356 struct sockaddr * addr = reinterpret_cast<struct sockaddr *>( const_cast<void *>(localaddr.getPlatformData()));
00357 assert(addr);
00358
00359 size_t actualsize = sizeof(sockaddr_storage);
00360 int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00361
00362 assert(actualsize <= sizeof(sockaddr_storage));
00363 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00364
00365 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00366 }
00367
00368 virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00369 {
00370 int ans;
00371 timeval tv;
00372 tv.tv_sec = timeout / 1000;
00373 tv.tv_usec = (timeout % 1000) * 1000;
00374
00375 if (msk & SOCKET_DIR_RD) {
00376 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00377 if (ans) return RESULT_OPERATION_FAIL;
00378 }
00379
00380 if (msk & SOCKET_DIR_WR) {
00381 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00382 if (ans) return RESULT_OPERATION_FAIL;
00383 }
00384
00385 return RESULT_OK;
00386 }
00387
00388 virtual u_result connect(const SocketAddress & pairAddress)
00389 {
00390 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(pairAddress.getPlatformData());
00391 int ans = ::connect(_socket_fd, addr, sizeof(sockaddr_storage));
00392 if (!ans) return RESULT_OK;
00393
00394
00395 switch (errno) {
00396 case EAFNOSUPPORT:
00397 return RESULT_OPERATION_NOT_SUPPORT;
00398 #if 0
00399 case EINPROGRESS:
00400 return RESULT_OK;
00401 #endif
00402 case ETIMEDOUT:
00403 return RESULT_OPERATION_TIMEOUT;
00404 default:
00405 return RESULT_OPERATION_FAIL;
00406 }
00407 }
00408
00409 virtual u_result listen(int backlog)
00410 {
00411 int ans = ::listen( _socket_fd, backlog);
00412
00413 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00414 }
00415
00416 virtual StreamSocket * accept(SocketAddress * pairAddress)
00417 {
00418 size_t addrsize;
00419 addrsize = sizeof(sockaddr_storage);
00420 int pair_socket = ::accept( _socket_fd, pairAddress?reinterpret_cast<struct sockaddr *>(const_cast<void *>(pairAddress->getPlatformData())):NULL
00421 , (socklen_t*)&addrsize);
00422
00423 if (pair_socket>=0) {
00424 return new StreamSocketImpl(pair_socket);
00425 } else {
00426 return NULL;
00427 }
00428 }
00429
00430 virtual u_result waitforIncomingConnection(_u32 timeout)
00431 {
00432 return waitforData(timeout);
00433 }
00434
00435 virtual u_result send(const void * buffer, size_t len)
00436 {
00437 size_t ans = ::send( _socket_fd, buffer, len, MSG_NOSIGNAL);
00438 if (ans == (int)len) {
00439 return RESULT_OK;
00440 } else {
00441 switch (errno) {
00442 case EAGAIN:
00443 #if EWOULDBLOCK!=EAGAIN
00444 case EWOULDBLOCK:
00445 #endif
00446 return RESULT_OPERATION_TIMEOUT;
00447 default:
00448 return RESULT_OPERATION_FAIL;
00449 }
00450 }
00451
00452 }
00453
00454
00455 virtual u_result recv(void *buf, size_t len, size_t & recv_len)
00456 {
00457 size_t ans = ::recv( _socket_fd, buf, len, 0);
00458 if (ans == (size_t)-1) {
00459 recv_len = 0;
00460
00461 switch (errno) {
00462 case EAGAIN:
00463 #if EWOULDBLOCK!=EAGAIN
00464 case EWOULDBLOCK:
00465 #endif
00466 return RESULT_OPERATION_TIMEOUT;
00467 default:
00468 return RESULT_OPERATION_FAIL;
00469 }
00470
00471
00472
00473 } else {
00474 recv_len = ans;
00475 return RESULT_OK;
00476 }
00477 }
00478
00479 #if 0
00480 virtual u_result recvNoWait(void *buf, size_t len, size_t & recv_len)
00481 {
00482 size_t ans = ::recv( _socket_fd, buf, len, MSG_DONTWAIT);
00483 if (ans == (size_t)-1) {
00484 recv_len = 0;
00485 if (errno == EAGAIN || errno == EWOULDBLOCK) {
00486 return RESULT_OK;
00487 } else {
00488 return RESULT_OPERATION_FAIL;
00489 }
00490
00491
00492 } else {
00493 recv_len = ans;
00494 return RESULT_OK;
00495 }
00496
00497 }
00498 #endif
00499
00500 virtual u_result getPeerAddress(SocketAddress & peerAddr)
00501 {
00502 struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>(peerAddr.getPlatformData()));
00503 assert(addr);
00504 size_t actualsize = sizeof(sockaddr_storage);
00505 int ans = ::getpeername(_socket_fd, addr, (socklen_t*)&actualsize);
00506
00507 assert(actualsize <= sizeof(sockaddr_storage));
00508 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00509
00510 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00511
00512 }
00513
00514 virtual u_result shutdown(socket_direction_mask mask)
00515 {
00516 int shutdw_opt ;
00517
00518 switch (mask) {
00519 case SOCKET_DIR_RD:
00520 shutdw_opt = SHUT_RD;
00521 break;
00522 case SOCKET_DIR_WR:
00523 shutdw_opt = SHUT_WR;
00524 break;
00525 case SOCKET_DIR_BOTH:
00526 default:
00527 shutdw_opt = SHUT_RDWR;
00528 }
00529
00530 int ans = ::shutdown(_socket_fd, shutdw_opt);
00531 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00532 }
00533
00534 virtual u_result enableKeepAlive(bool enable)
00535 {
00536 int bool_true = enable?1:0;
00537 return ::setsockopt( _socket_fd, SOL_SOCKET, SO_KEEPALIVE , &bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00538 }
00539
00540 virtual u_result enableNoDelay(bool enable )
00541 {
00542 int bool_true = enable?1:0;
00543 return ::setsockopt( _socket_fd, IPPROTO_TCP, TCP_NODELAY,&bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00544 }
00545
00546 virtual u_result waitforSent(_u32 timeout )
00547 {
00548 fd_set wrset;
00549 FD_ZERO(&wrset);
00550 FD_SET(_socket_fd, &wrset);
00551
00552 timeval tv;
00553 tv.tv_sec = timeout / 1000;
00554 tv.tv_usec = (timeout % 1000) * 1000;
00555 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00556
00557 switch (ans) {
00558 case 1:
00559
00560 return RESULT_OK;
00561 case 0:
00562
00563 return RESULT_OPERATION_TIMEOUT;
00564 default:
00565 delay(0);
00566 return RESULT_OPERATION_FAIL;
00567 }
00568 }
00569
00570 virtual u_result waitforData(_u32 timeout )
00571 {
00572 fd_set rdset;
00573 FD_ZERO(&rdset);
00574 FD_SET(_socket_fd, &rdset);
00575
00576 timeval tv;
00577 tv.tv_sec = timeout / 1000;
00578 tv.tv_usec = (timeout % 1000) * 1000;
00579 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00580
00581 switch (ans) {
00582 case 1:
00583
00584 return RESULT_OK;
00585 case 0:
00586
00587 return RESULT_OPERATION_TIMEOUT;
00588 default:
00589 delay(0);
00590 return RESULT_OPERATION_FAIL;
00591 }
00592 }
00593
00594 protected:
00595 int _socket_fd;
00596
00597
00598 };
00599
00600
00601 class _single_thread DGramSocketImpl : public DGramSocket
00602 {
00603 public:
00604
00605 DGramSocketImpl(int fd)
00606 : _socket_fd(fd)
00607 {
00608 assert(fd>=0);
00609 int bool_true = 1;
00610 ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (char *)&bool_true, sizeof(bool_true) );
00611 setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00612 }
00613
00614 virtual ~DGramSocketImpl()
00615 {
00616 close(_socket_fd);
00617 }
00618
00619 virtual void dispose()
00620 {
00621 delete this;
00622 }
00623
00624
00625 virtual u_result bind(const SocketAddress & localaddr)
00626 {
00627 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00628 assert(addr);
00629 int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00630 if (ans) {
00631 return RESULT_OPERATION_FAIL;
00632 } else {
00633 return RESULT_OK;
00634 }
00635 }
00636
00637 virtual u_result getLocalAddress(SocketAddress & localaddr)
00638 {
00639 struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>((localaddr.getPlatformData())));
00640 assert(addr);
00641
00642 size_t actualsize = sizeof(sockaddr_storage);
00643 int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00644
00645 assert(actualsize <= sizeof(sockaddr_storage));
00646 assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00647
00648 return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00649 }
00650
00651 virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00652 {
00653 int ans;
00654 timeval tv;
00655 tv.tv_sec = timeout / 1000;
00656 tv.tv_usec = (timeout % 1000) * 1000;
00657
00658 if (msk & SOCKET_DIR_RD) {
00659 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00660 if (ans) return RESULT_OPERATION_FAIL;
00661 }
00662
00663 if (msk & SOCKET_DIR_WR) {
00664 ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00665 if (ans) return RESULT_OPERATION_FAIL;
00666 }
00667
00668 return RESULT_OK;
00669 }
00670
00671
00672 virtual u_result waitforSent(_u32 timeout )
00673 {
00674 fd_set wrset;
00675 FD_ZERO(&wrset);
00676 FD_SET(_socket_fd, &wrset);
00677
00678 timeval tv;
00679 tv.tv_sec = timeout / 1000;
00680 tv.tv_usec = (timeout % 1000) * 1000;
00681 int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00682
00683 switch (ans) {
00684 case 1:
00685
00686 return RESULT_OK;
00687 case 0:
00688
00689 return RESULT_OPERATION_TIMEOUT;
00690 default:
00691 delay(0);
00692 return RESULT_OPERATION_FAIL;
00693 }
00694 }
00695
00696 virtual u_result waitforData(_u32 timeout )
00697 {
00698 fd_set rdset;
00699 FD_ZERO(&rdset);
00700 FD_SET(_socket_fd, &rdset);
00701
00702 timeval tv;
00703 tv.tv_sec = timeout / 1000;
00704 tv.tv_usec = (timeout % 1000) * 1000;
00705 int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00706
00707 switch (ans) {
00708 case 1:
00709
00710 return RESULT_OK;
00711 case 0:
00712
00713 return RESULT_OPERATION_TIMEOUT;
00714 default:
00715 delay(0);
00716 return RESULT_OPERATION_FAIL;
00717 }
00718 }
00719
00720 virtual u_result sendTo(const SocketAddress & target, const void * buffer, size_t len)
00721 {
00722 const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(target.getPlatformData());
00723 assert(addr);
00724 size_t ans = ::sendto( _socket_fd, buffer, len, 0, addr, sizeof(sockaddr_storage));
00725 if (ans != (size_t)-1) {
00726 assert(ans == (int)len);
00727 return RESULT_OK;
00728 } else {
00729 switch (errno) {
00730 case EAGAIN:
00731 #if EWOULDBLOCK!=EAGAIN
00732 case EWOULDBLOCK:
00733 #endif
00734 return RESULT_OPERATION_TIMEOUT;
00735
00736 case EMSGSIZE:
00737 return RESULT_INVALID_DATA;
00738 default:
00739 return RESULT_OPERATION_FAIL;
00740 }
00741
00742 }
00743
00744 }
00745
00746
00747 virtual u_result recvFrom(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00748 {
00749 struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00750 size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00751
00752 size_t ans = ::recvfrom( _socket_fd, buf, len, 0, addr, (socklen_t*)&source_addr_size);
00753 if (ans == (size_t)-1) {
00754 recv_len = 0;
00755 switch (errno) {
00756 case EAGAIN:
00757 #if EWOULDBLOCK!=EAGAIN
00758 case EWOULDBLOCK:
00759 #endif
00760 return RESULT_OPERATION_TIMEOUT;
00761 default:
00762 return RESULT_OPERATION_FAIL;
00763 }
00764
00765 } else {
00766 recv_len = ans;
00767 return RESULT_OK;
00768 }
00769
00770 }
00771
00772 #if 0
00773 virtual u_result recvFromNoWait(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00774 {
00775 struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00776 size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00777
00778
00779 size_t ans = ::recvfrom( _socket_fd, buf, len, MSG_DONTWAIT, addr, &source_addr_size);
00780
00781 if (ans == (size_t)-1) {
00782 recv_len = 0;
00783 if (errno == EAGAIN || errno == EWOULDBLOCK) {
00784 return RESULT_OK;
00785 } else {
00786 return RESULT_OPERATION_FAIL;
00787 }
00788
00789
00790 } else {
00791 recv_len = ans;
00792 return RESULT_OK;
00793 }
00794
00795 }
00796 #endif
00797
00798 protected:
00799 int _socket_fd;
00800
00801 };
00802
00803
00804 }}}
00805
00806
00807 namespace rp { namespace net{
00808
00809
00810 static inline int _socketHalFamilyToOSFamily(SocketBase::socket_family_t family)
00811 {
00812 switch (family) {
00813 case SocketBase::SOCKET_FAMILY_INET:
00814 return AF_INET;
00815 case SocketBase::SOCKET_FAMILY_INET6:
00816 return AF_INET6;
00817 case SocketBase::SOCKET_FAMILY_RAW:
00818 return AF_PACKET;
00819 default:
00820 assert(!"should not reach here");
00821 return AF_INET;
00822 }
00823
00824 }
00825
00826 StreamSocket * StreamSocket::CreateSocket(SocketBase::socket_family_t family)
00827 {
00828 if (family == SOCKET_FAMILY_RAW) return NULL;
00829
00830
00831 int socket_family = _socketHalFamilyToOSFamily(family);
00832 int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
00833 if (socket_fd == -1) return NULL;
00834
00835 StreamSocket * newborn = static_cast<StreamSocket *>(new rp::arch::net::StreamSocketImpl(socket_fd));
00836 return newborn;
00837
00838 }
00839
00840
00841 DGramSocket * DGramSocket::CreateSocket(SocketBase::socket_family_t family)
00842 {
00843 int socket_family = _socketHalFamilyToOSFamily(family);
00844
00845
00846 int socket_fd = ::socket(socket_family, (family==SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
00847 if (socket_fd == -1) return NULL;
00848
00849 DGramSocket * newborn = static_cast<DGramSocket *>(new rp::arch::net::DGramSocketImpl(socket_fd));
00850 return newborn;
00851
00852 }
00853
00854
00855 }}
00856