00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackNetUnixSocket.h"
00021 #include "JackError.h"
00022
00023 #include <unistd.h>
00024 #include <fcntl.h>
00025
00026 using namespace std;
00027
00028 namespace Jack
00029 {
00030
00031 int GetHostName(char * name, int size)
00032 {
00033 if (gethostname(name, size) == SOCKET_ERROR) {
00034 jack_error("Can't get 'hostname' : %s", strerror(NET_ERROR_CODE));
00035 strcpy(name, "default");
00036 return SOCKET_ERROR;
00037 }
00038 return 0;
00039 }
00040
00041
00042 JackNetUnixSocket::JackNetUnixSocket()
00043 {
00044 fSockfd = 0;
00045 fPort = 0;
00046 fTimeOut = 0;
00047 fSendAddr.sin_family = AF_INET;
00048 fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00049 memset(&fSendAddr.sin_zero, 0, 8);
00050 fRecvAddr.sin_family = AF_INET;
00051 fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00052 memset(&fRecvAddr.sin_zero, 0, 8);
00053 }
00054
00055 JackNetUnixSocket::JackNetUnixSocket(const char* ip, int port)
00056 {
00057 fSockfd = 0;
00058 fPort = port;
00059 fTimeOut = 0;
00060 fSendAddr.sin_family = AF_INET;
00061 fSendAddr.sin_port = htons(port);
00062 inet_aton(ip, &fSendAddr.sin_addr);
00063 memset(&fSendAddr.sin_zero, 0, 8);
00064 fRecvAddr.sin_family = AF_INET;
00065 fRecvAddr.sin_port = htons(port);
00066 fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00067 memset(&fRecvAddr.sin_zero, 0, 8);
00068 }
00069
00070 JackNetUnixSocket::JackNetUnixSocket(const JackNetUnixSocket& socket)
00071 {
00072 fSockfd = 0;
00073 fTimeOut = 0;
00074 fPort = socket.fPort;
00075 fSendAddr = socket.fSendAddr;
00076 fRecvAddr = socket.fRecvAddr;
00077 }
00078
00079 JackNetUnixSocket::~JackNetUnixSocket()
00080 {
00081 Close();
00082 }
00083
00084 JackNetUnixSocket& JackNetUnixSocket::operator=(const JackNetUnixSocket& socket)
00085 {
00086 if (this != &socket) {
00087 fSockfd = 0;
00088 fPort = socket.fPort;
00089 fSendAddr = socket.fSendAddr;
00090 fRecvAddr = socket.fRecvAddr;
00091 }
00092 return *this;
00093 }
00094
00095
00096 int JackNetUnixSocket::NewSocket()
00097 {
00098 if (fSockfd) {
00099 Close();
00100 Reset();
00101 }
00102 fSockfd = socket(AF_INET, SOCK_DGRAM, 0);
00103
00104
00105 int res, on = 1;
00106 #ifdef __APPLE__
00107 if ((res = setsockopt(fSockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) < 0) {
00108 #else
00109 if ((res = setsockopt(fSockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) {
00110 #endif
00111 StrError(NET_ERROR_CODE);
00112 }
00113 return fSockfd;
00114 }
00115
00116 bool JackNetUnixSocket::IsLocal(char* ip)
00117 {
00118 if (strcmp(ip, "127.0.0.1") == 0) {
00119 return true;
00120 }
00121
00122 char host_name[32];
00123 gethostname(host_name, sizeof(host_name));
00124
00125 struct hostent* host = gethostbyname(host_name);
00126 if (host) {
00127 for (int i = 0; host->h_addr_list[i] != 0; ++i) {
00128 struct in_addr addr;
00129 memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr));
00130 if (strcmp(inet_ntoa(addr), ip) == 0) {
00131 return true;
00132 }
00133 }
00134 return false;
00135 } else {
00136 return false;
00137 }
00138 }
00139
00140 int JackNetUnixSocket::Bind()
00141 {
00142 return bind(fSockfd, reinterpret_cast<socket_address_t*>(&fRecvAddr), sizeof(socket_address_t));
00143 }
00144
00145 int JackNetUnixSocket::BindWith(const char* ip)
00146 {
00147 int addr_conv = inet_aton(ip, &fRecvAddr.sin_addr);
00148 if (addr_conv < 0) {
00149 return addr_conv;
00150 }
00151 return Bind();
00152 }
00153
00154 int JackNetUnixSocket::BindWith(int port)
00155 {
00156 fRecvAddr.sin_port = htons(port);
00157 return Bind();
00158 }
00159
00160 int JackNetUnixSocket::Connect()
00161 {
00162 return connect(fSockfd, reinterpret_cast<socket_address_t*>(&fSendAddr), sizeof(socket_address_t));
00163 }
00164
00165 int JackNetUnixSocket::ConnectTo(const char* ip)
00166 {
00167 int addr_conv = inet_aton(ip, &fSendAddr.sin_addr);
00168 if (addr_conv < 0) {
00169 return addr_conv;
00170 }
00171 return Connect();
00172 }
00173
00174 void JackNetUnixSocket::Close()
00175 {
00176 if (fSockfd) {
00177 close(fSockfd);
00178 }
00179 fSockfd = 0;
00180 }
00181
00182 void JackNetUnixSocket::Reset()
00183 {
00184 fSendAddr.sin_family = AF_INET;
00185 fSendAddr.sin_port = htons(fPort);
00186 fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00187 memset(&fSendAddr.sin_zero, 0, 8);
00188 fRecvAddr.sin_family = AF_INET;
00189 fRecvAddr.sin_port = htons(fPort);
00190 fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00191 memset(&fRecvAddr.sin_zero, 0, 8);
00192 }
00193
00194 bool JackNetUnixSocket::IsSocket()
00195 {
00196 return(fSockfd) ? true : false;
00197 }
00198
00199
00200 void JackNetUnixSocket::SetPort(int port)
00201 {
00202 fPort = port;
00203 fSendAddr.sin_port = htons(port);
00204 fRecvAddr.sin_port = htons(port);
00205 }
00206
00207 int JackNetUnixSocket::GetPort()
00208 {
00209 return fPort;
00210 }
00211
00212
00213 int JackNetUnixSocket::SetAddress(const char* ip, int port)
00214 {
00215 int addr_conv = inet_aton(ip, &fSendAddr.sin_addr);
00216 if (addr_conv < 0) {
00217 return addr_conv;
00218 }
00219 fSendAddr.sin_port = htons(port);
00220 return 0;
00221 }
00222
00223 char* JackNetUnixSocket::GetSendIP()
00224 {
00225 return inet_ntoa(fSendAddr.sin_addr);
00226 }
00227
00228 char* JackNetUnixSocket::GetRecvIP()
00229 {
00230 return inet_ntoa(fRecvAddr.sin_addr);
00231 }
00232
00233
00234 int JackNetUnixSocket::GetName(char* name)
00235 {
00236 return gethostname(name, 255);
00237 }
00238
00239 int JackNetUnixSocket::JoinMCastGroup(const char* ip)
00240 {
00241 struct ip_mreq multicast_req;
00242 inet_aton(ip, &multicast_req.imr_multiaddr);
00243 multicast_req.imr_interface.s_addr = htonl(INADDR_ANY);
00244 return SetOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof(multicast_req));
00245 }
00246
00247
00248 int JackNetUnixSocket::SetOption(int level, int optname, const void* optval, socklen_t optlen)
00249 {
00250 return setsockopt(fSockfd, level, optname, optval, optlen);
00251 }
00252
00253 int JackNetUnixSocket::GetOption(int level, int optname, void* optval, socklen_t* optlen)
00254 {
00255 return getsockopt(fSockfd, level, optname, optval, optlen);
00256 }
00257
00258
00259
00260 #if defined(__sun__) || defined(sun)
00261 int JackNetUnixSocket::SetTimeOut(int us)
00262 {
00263 int flags;
00264 fTimeOut = us;
00265
00266 if ((flags = fcntl(fSockfd, F_GETFL, 0)) < 0) {
00267 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_GETFL");
00268 return -1;
00269 }
00270
00271 flags |= O_NONBLOCK;
00272 if (fcntl(fSockfd, F_SETFL, flags) < 0) {
00273 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_SETFL");
00274 return 1;
00275 }
00276
00277 return 0;
00278 }
00279
00280 int JackNetUnixSocket::WaitRead()
00281 {
00282 if (fTimeOut > 0) {
00283
00284 struct timeval tv;
00285 fd_set fdset;
00286 ssize_t res;
00287
00288 tv.tv_sec = fTimeOut / 1000000;
00289 tv.tv_usec = fTimeOut % 1000000;
00290
00291 FD_ZERO(&fdset);
00292 FD_SET(fSockfd, &fdset);
00293
00294 do {
00295 res = select(fSockfd + 1, &fdset, NULL, NULL, &tv);
00296 } while (res < 0 && errno == EINTR);
00297
00298 if (res < 0) {
00299 return res;
00300 } else if (res == 0) {
00301 errno = ETIMEDOUT;
00302 return -1;
00303 }
00304 }
00305
00306 return 0;
00307 }
00308
00309 int JackNetUnixSocket::WaitWrite()
00310 {
00311 if (fTimeOut > 0) {
00312
00313 struct timeval tv;
00314 fd_set fdset;
00315 ssize_t res;
00316
00317 tv.tv_sec = fTimeOut / 1000000;
00318 tv.tv_usec = fTimeOut % 1000000;
00319
00320 FD_ZERO(&fdset);
00321 FD_SET(fSockfd, &fdset);
00322
00323 do {
00324 res = select(fSockfd + 1, NULL, &fdset, NULL, &tv);
00325 } while (res < 0 && errno == EINTR);
00326
00327 if (res < 0) {
00328 return res;
00329 } else if (res == 0) {
00330 errno = ETIMEDOUT;
00331 return -1;
00332 }
00333 }
00334
00335 return 0;
00336 }
00337
00338 #else
00339 int JackNetUnixSocket::SetTimeOut(int us)
00340 {
00341 jack_log("JackNetUnixSocket::SetTimeout %d usecs", us);
00342 struct timeval timeout;
00343
00344
00345 if (us < 1000000) {
00346 timeout.tv_sec = 0;
00347 timeout.tv_usec = us;
00348 } else {
00349
00350 float sec = float(us) / 1000000.f;
00351 timeout.tv_sec = (int)sec;
00352 float usec = (sec - float(timeout.tv_sec)) * 1000000;
00353 timeout.tv_usec =(int)usec;
00354 }
00355 return SetOption(SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
00356 }
00357 #endif
00358
00359
00360 int JackNetUnixSocket::SetLocalLoop()
00361 {
00362 char disable = 0;
00363 return SetOption(IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof(disable));
00364 }
00365
00366
00367 int JackNetUnixSocket::SendTo(const void* buffer, size_t nbytes, int flags)
00368 {
00369 #if defined(__sun__) || defined(sun)
00370 if (WaitWrite() < 0) {
00371 return -1;
00372 }
00373 #endif
00374 int res;
00375 if ((res = sendto(fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*>(&fSendAddr), sizeof(socket_address_t))) < 0) {
00376 jack_error("SendTo fd = %ld err = %s", fSockfd, strerror(errno));
00377 }
00378 return res;
00379 }
00380
00381 int JackNetUnixSocket::SendTo(const void* buffer, size_t nbytes, int flags, const char* ip)
00382 {
00383 int addr_conv = inet_aton(ip, &fSendAddr.sin_addr);
00384 if (addr_conv < 1) {
00385 return addr_conv;
00386 }
00387 #if defined(__sun__) || defined(sun)
00388 if (WaitWrite() < 0) {
00389 return -1;
00390 }
00391 #endif
00392 return SendTo(buffer, nbytes, flags);
00393 }
00394
00395 int JackNetUnixSocket::Send(const void* buffer, size_t nbytes, int flags)
00396 {
00397 #if defined(__sun__) || defined(sun)
00398 if (WaitWrite() < 0) {
00399 return -1;
00400 }
00401 #endif
00402 int res;
00403 if ((res = send(fSockfd, buffer, nbytes, flags)) < 0) {
00404 jack_error("Send fd = %ld err = %s", fSockfd, strerror(errno));
00405 }
00406 return res;
00407 }
00408
00409 int JackNetUnixSocket::RecvFrom(void* buffer, size_t nbytes, int flags)
00410 {
00411 socklen_t addr_len = sizeof(socket_address_t);
00412 #if defined(__sun__) || defined(sun)
00413 if (WaitRead() < 0) {
00414 return -1;
00415 }
00416 #endif
00417 int res;
00418 if ((res = recvfrom(fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*>(&fRecvAddr), &addr_len)) < 0) {
00419 jack_error("RecvFrom fd = %ld err = %s", fSockfd, strerror(errno));
00420 }
00421 return res;
00422 }
00423
00424 int JackNetUnixSocket::Recv(void* buffer, size_t nbytes, int flags)
00425 {
00426 #if defined(__sun__) || defined(sun)
00427 if (WaitRead() < 0) {
00428 return -1;
00429 }
00430 #endif
00431 int res;
00432 if ((res = recv(fSockfd, buffer, nbytes, flags)) < 0) {
00433 jack_error("Recv fd = %ld err = %s", fSockfd, strerror(errno));
00434 }
00435 return res;
00436 }
00437
00438 int JackNetUnixSocket::CatchHost(void* buffer, size_t nbytes, int flags)
00439 {
00440 socklen_t addr_len = sizeof(socket_address_t);
00441 #if defined(__sun__) || defined(sun)
00442 if (WaitRead() < 0) {
00443 return -1;
00444 }
00445 #endif
00446 int res;
00447 if ((res = recvfrom(fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*>(&fSendAddr), &addr_len)) < 0) {
00448 jack_log("CatchHost fd = %ld err = %s", fSockfd, strerror(errno));
00449 }
00450 return res;
00451 }
00452
00453 net_error_t JackNetUnixSocket::GetError()
00454 {
00455 switch (errno) {
00456 case EAGAIN:
00457 case ETIMEDOUT:
00458 return NET_NO_DATA;
00459
00460 case ECONNABORTED:
00461 case ECONNREFUSED:
00462 case ECONNRESET:
00463 case EINVAL:
00464 case EHOSTDOWN:
00465 case EHOSTUNREACH:
00466 case ENETDOWN:
00467 case ENETUNREACH:
00468 return NET_CONN_ERROR;
00469
00470 default:
00471
00472 return NET_CONN_ERROR;
00473 }
00474 }
00475
00476 void JackNetUnixSocket::PrintError()
00477 {
00478 switch (errno) {
00479
00480 case EAGAIN:
00481 jack_error("JackNetUnixSocket : EAGAIN");
00482 break;
00483 case ETIMEDOUT:
00484 jack_error("JackNetUnixSocket : ETIMEDOUT");
00485 break;
00486 case ECONNABORTED:
00487 jack_error("JackNetUnixSocket : ECONNABORTED");
00488 break;
00489 case ECONNREFUSED:
00490 jack_error("JackNetUnixSocket : ECONNREFUSED");
00491 break;
00492 case ECONNRESET:
00493 jack_error("JackNetUnixSocket : ECONNRESET");
00494 break;
00495 case EINVAL:
00496 jack_error("JackNetUnixSocket : EINVAL");
00497 break;
00498 case EHOSTDOWN:
00499 jack_error("JackNetUnixSocket : EHOSTDOWN");
00500 break;
00501 case EHOSTUNREACH:
00502 jack_error("JackNetUnixSocket : EHOSTUNREACH");
00503 break;
00504 case ENETDOWN:
00505 jack_error("JackNetUnixSocket : ENETDOWN");
00506 break;
00507 case ENETUNREACH:
00508 jack_error("JackNetUnixSocket : ENETUNREACH");
00509 break;
00510 default:
00511 jack_error("JackNetUnixSocket : %d", errno);
00512 break;
00513 }
00514 }
00515 }