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