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