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