diff options
Diffstat (limited to 'cs/src/Ice/Network.cs')
-rwxr-xr-x | cs/src/Ice/Network.cs | 1958 |
1 files changed, 979 insertions, 979 deletions
diff --git a/cs/src/Ice/Network.cs b/cs/src/Ice/Network.cs index 283d54e9d62..b3f7cb32b8e 100755 --- a/cs/src/Ice/Network.cs +++ b/cs/src/Ice/Network.cs @@ -21,724 +21,724 @@ namespace IceInternal public sealed class Network { - // - // Magic numbers taken from winsock2.h - // - const int WSAEINTR = 10004; - const int WSAEFAULT = 10014; - const int WSAEINVAL = 10022; - const int WSAEWOULDBLOCK = 10035; - const int WSAEINPROGRESS = 10036; // Deprecated in winsock2, but still used by Mono Beta 1 - const int WSAEMSGSIZE = 10040; - const int WSAENETDOWN = 10050; - const int WSAENETUNREACH = 10051; - const int WSAENETRESET = 10052; - const int WSAECONNABORTED = 10053; - const int WSAECONNRESET = 10054; - const int WSAENOBUFS = 10055; - const int WSAENOTCONN = 10057; - const int WSAESHUTDOWN = 10058; - const int WSAETIMEDOUT = 10060; - const int WSAECONNREFUSED = 10061; - const int WSAEHOSTUNREACH = 10065; - const int WSATRY_AGAIN = 11002; - - public static bool interrupted(Win32Exception ex) - { - return ex.NativeErrorCode == WSAEINTR; - } - - public static bool acceptInterrupted(Win32Exception ex) - { - if(interrupted(ex)) - { - return true; - } - int error = ex.NativeErrorCode; - return error == WSAECONNABORTED || - error == WSAECONNRESET || - error == WSAETIMEDOUT; - } - - public static bool noBuffers(Win32Exception ex) - { - int error = ex.NativeErrorCode; - return error == WSAENOBUFS || - error == WSAEFAULT; - } - - public static bool wouldBlock(Win32Exception ex) - { - return ex.NativeErrorCode == WSAEWOULDBLOCK; - } - - public static bool connectFailed(Win32Exception ex) - { - int error = ex.NativeErrorCode; - return error == WSAECONNREFUSED || - error == WSAETIMEDOUT || - error == WSAENETUNREACH || - error == WSAEHOSTUNREACH || - error == WSAECONNRESET || - error == WSAESHUTDOWN || - error == WSAECONNABORTED || - error == WSAENETDOWN; - } - - public static bool connectInProgress(Win32Exception ex) - { - int error = ex.NativeErrorCode; - return error == WSAEWOULDBLOCK || - error == WSAEINPROGRESS; - } - - public static bool connectionLost(Win32Exception ex) - { - int error = ex.NativeErrorCode; - return error == WSAECONNRESET || - error == WSAESHUTDOWN || - error == WSAECONNABORTED || - error == WSAENETDOWN || - error == WSAENETRESET; - } - - public static bool connectionLost(System.IO.IOException ex) - { - string msg = ex.Message.ToLower(); - return msg.IndexOf("connection was forcibly closed") >= 0 || - msg.IndexOf("remote party has closed the transport stream") >= 0 || - msg.IndexOf("established connection was aborted") >= 0 || - msg.IndexOf("received an unexpected eof or 0 bytes from the transport stream") >= 0; - } - - public static bool connectionRefused(Win32Exception ex) - { - return ex.NativeErrorCode == WSAECONNREFUSED; - } - - public static bool notConnected(Win32Exception ex) - { - // BUGFIX: WSAEINVAL because shutdown() under MacOS returns EINVAL if the server side is gone. - return ex.NativeErrorCode == WSAENOTCONN || ex.NativeErrorCode == WSAEINVAL; - } - - public static bool recvTruncated(Win32Exception ex) - { - return ex.NativeErrorCode == WSAEMSGSIZE; - } - - public static bool timeout(System.IO.IOException ex) - { - return ex.Message.IndexOf("period of time") >= 0; - } - - public static Socket createSocket(bool udp) - { - Socket socket; - - try - { - if(udp) - { - socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - } - else - { - socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - } - } - catch(SocketException ex) - { - throw new Ice.SocketException("Cannot create socket", ex); - } - - if(!udp) - { - try - { - setTcpNoDelay(socket); - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1); - } - catch(SocketException ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot set socket options", ex); - } - } - return socket; - } - - public static void closeSocketNoThrow(Socket socket) - { - if(socket == null) - { - return; - } - try - { - socket.Close(); - } - catch(SocketException) - { - // Ignore - } - } - - public static void closeSocket(Socket socket) - { - if(socket == null) - { - return; - } - try - { - socket.Close(); - } - catch(SocketException ex) - { - throw new Ice.SocketException("Cannot close socket", ex); - } - } - - public static void setBlock(Socket socket, bool block) - { - try - { - socket.Blocking = block; - } - catch(SocketException ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException(ex); - } - } - - public static void setTcpNoDelay(Socket socket) - { - try - { - socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1); - } - catch(System.Exception ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot set NoDelay option", ex); - } - } - - public static void setKeepAlive(Socket socket) - { - try - { - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1); - } - catch(System.Exception ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot set KeepAlive option", ex); - } - } - - public static void setSendBufferSize(Socket socket, int sz) - { - try - { - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, sz); - } - catch(SocketException ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot set send buffer size", ex); - } - } - - public static int getSendBufferSize(Socket socket) - { - int sz; - try - { - sz = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer); - } - catch(SocketException ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot read send buffer size", ex); - } - return sz; - } - - public static void setRecvBufferSize(Socket socket, int sz) - { - try - { - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, sz); - } - catch(SocketException ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot set receive buffer size", ex); - } - } - - public static int getRecvBufferSize(Socket socket) - { - int sz = 0; - try - { - sz = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer); - } - catch(SocketException ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot read receive buffer size", ex); - } - return sz; - } - - public static IPEndPoint doBind(Socket socket, EndPoint addr) - { - try - { - // - // Don't set ReuseAddress on Win32 -- it allows two processes to bind to the same port! - // - //socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); - socket.Bind(addr); - return (IPEndPoint)socket.LocalEndPoint; - } - catch(SocketException ex) - { - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot bind", ex); - } - } - - public static void doListen(Socket socket, int backlog) - { - repeatListen: - - try - { - socket.Listen(backlog); - } - catch(SocketException ex) - { - if(interrupted(ex)) - { - goto repeatListen; - } - - closeSocketNoThrow(socket); - throw new Ice.SocketException("Cannot listen", ex); - } - } - - public static void doConnect(Socket socket, EndPoint addr, int timeout) - { - // - // MONO workaround for - // http://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=1647. - // - // It would have been nice to be able to get rid of the 2 - // implementations of doConnect() and only use - // doConnectAsync() however, with .NET doConnectAsync() - // doesn't work with the TCP transport. In particular, - // the test/Ice/timeout test fails in the connect timeout - // test because the client hangs in the Receive() call - // waiting for the connection validation (for some reasons - // Receive blocks even though the socket is - // non-blocking...) - // - if(AssemblyUtil.runtime_ == AssemblyUtil.Runtime.Mono) - { - doConnectAsync(socket, addr, timeout); - return; - } + // + // Magic numbers taken from winsock2.h + // + const int WSAEINTR = 10004; + const int WSAEFAULT = 10014; + const int WSAEINVAL = 10022; + const int WSAEWOULDBLOCK = 10035; + const int WSAEINPROGRESS = 10036; // Deprecated in winsock2, but still used by Mono Beta 1 + const int WSAEMSGSIZE = 10040; + const int WSAENETDOWN = 10050; + const int WSAENETUNREACH = 10051; + const int WSAENETRESET = 10052; + const int WSAECONNABORTED = 10053; + const int WSAECONNRESET = 10054; + const int WSAENOBUFS = 10055; + const int WSAENOTCONN = 10057; + const int WSAESHUTDOWN = 10058; + const int WSAETIMEDOUT = 10060; + const int WSAECONNREFUSED = 10061; + const int WSAEHOSTUNREACH = 10065; + const int WSATRY_AGAIN = 11002; + + public static bool interrupted(Win32Exception ex) + { + return ex.NativeErrorCode == WSAEINTR; + } + + public static bool acceptInterrupted(Win32Exception ex) + { + if(interrupted(ex)) + { + return true; + } + int error = ex.NativeErrorCode; + return error == WSAECONNABORTED || + error == WSAECONNRESET || + error == WSAETIMEDOUT; + } + + public static bool noBuffers(Win32Exception ex) + { + int error = ex.NativeErrorCode; + return error == WSAENOBUFS || + error == WSAEFAULT; + } + + public static bool wouldBlock(Win32Exception ex) + { + return ex.NativeErrorCode == WSAEWOULDBLOCK; + } + + public static bool connectFailed(Win32Exception ex) + { + int error = ex.NativeErrorCode; + return error == WSAECONNREFUSED || + error == WSAETIMEDOUT || + error == WSAENETUNREACH || + error == WSAEHOSTUNREACH || + error == WSAECONNRESET || + error == WSAESHUTDOWN || + error == WSAECONNABORTED || + error == WSAENETDOWN; + } + + public static bool connectInProgress(Win32Exception ex) + { + int error = ex.NativeErrorCode; + return error == WSAEWOULDBLOCK || + error == WSAEINPROGRESS; + } + + public static bool connectionLost(Win32Exception ex) + { + int error = ex.NativeErrorCode; + return error == WSAECONNRESET || + error == WSAESHUTDOWN || + error == WSAECONNABORTED || + error == WSAENETDOWN || + error == WSAENETRESET; + } + + public static bool connectionLost(System.IO.IOException ex) + { + string msg = ex.Message.ToLower(); + return msg.IndexOf("connection was forcibly closed") >= 0 || + msg.IndexOf("remote party has closed the transport stream") >= 0 || + msg.IndexOf("established connection was aborted") >= 0 || + msg.IndexOf("received an unexpected eof or 0 bytes from the transport stream") >= 0; + } + + public static bool connectionRefused(Win32Exception ex) + { + return ex.NativeErrorCode == WSAECONNREFUSED; + } + + public static bool notConnected(Win32Exception ex) + { + // BUGFIX: WSAEINVAL because shutdown() under MacOS returns EINVAL if the server side is gone. + return ex.NativeErrorCode == WSAENOTCONN || ex.NativeErrorCode == WSAEINVAL; + } + + public static bool recvTruncated(Win32Exception ex) + { + return ex.NativeErrorCode == WSAEMSGSIZE; + } + + public static bool timeout(System.IO.IOException ex) + { + return ex.Message.IndexOf("period of time") >= 0; + } + + public static Socket createSocket(bool udp) + { + Socket socket; + + try + { + if(udp) + { + socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + } + else + { + socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + } + } + catch(SocketException ex) + { + throw new Ice.SocketException("Cannot create socket", ex); + } + + if(!udp) + { + try + { + setTcpNoDelay(socket); + socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1); + } + catch(SocketException ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot set socket options", ex); + } + } + return socket; + } + + public static void closeSocketNoThrow(Socket socket) + { + if(socket == null) + { + return; + } + try + { + socket.Close(); + } + catch(SocketException) + { + // Ignore + } + } + + public static void closeSocket(Socket socket) + { + if(socket == null) + { + return; + } + try + { + socket.Close(); + } + catch(SocketException ex) + { + throw new Ice.SocketException("Cannot close socket", ex); + } + } + + public static void setBlock(Socket socket, bool block) + { + try + { + socket.Blocking = block; + } + catch(SocketException ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException(ex); + } + } + + public static void setTcpNoDelay(Socket socket) + { + try + { + socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1); + } + catch(System.Exception ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot set NoDelay option", ex); + } + } + + public static void setKeepAlive(Socket socket) + { + try + { + socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1); + } + catch(System.Exception ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot set KeepAlive option", ex); + } + } + + public static void setSendBufferSize(Socket socket, int sz) + { + try + { + socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, sz); + } + catch(SocketException ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot set send buffer size", ex); + } + } + + public static int getSendBufferSize(Socket socket) + { + int sz; + try + { + sz = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer); + } + catch(SocketException ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot read send buffer size", ex); + } + return sz; + } + + public static void setRecvBufferSize(Socket socket, int sz) + { + try + { + socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, sz); + } + catch(SocketException ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot set receive buffer size", ex); + } + } + + public static int getRecvBufferSize(Socket socket) + { + int sz = 0; + try + { + sz = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer); + } + catch(SocketException ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot read receive buffer size", ex); + } + return sz; + } + + public static IPEndPoint doBind(Socket socket, EndPoint addr) + { + try + { + // + // Don't set ReuseAddress on Win32 -- it allows two processes to bind to the same port! + // + //socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); + socket.Bind(addr); + return (IPEndPoint)socket.LocalEndPoint; + } + catch(SocketException ex) + { + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot bind", ex); + } + } + + public static void doListen(Socket socket, int backlog) + { + repeatListen: + + try + { + socket.Listen(backlog); + } + catch(SocketException ex) + { + if(interrupted(ex)) + { + goto repeatListen; + } + + closeSocketNoThrow(socket); + throw new Ice.SocketException("Cannot listen", ex); + } + } + + public static void doConnect(Socket socket, EndPoint addr, int timeout) + { + // + // MONO workaround for + // http://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=1647. + // + // It would have been nice to be able to get rid of the 2 + // implementations of doConnect() and only use + // doConnectAsync() however, with .NET doConnectAsync() + // doesn't work with the TCP transport. In particular, + // the test/Ice/timeout test fails in the connect timeout + // test because the client hangs in the Receive() call + // waiting for the connection validation (for some reasons + // Receive blocks even though the socket is + // non-blocking...) + // + if(AssemblyUtil.runtime_ == AssemblyUtil.Runtime.Mono) + { + doConnectAsync(socket, addr, timeout); + return; + } // // Set larger send buffer size to avoid performance problems on // WIN32. // - if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) - { - setSendBufferSize(socket, 64 * 1024); - } - - repeatConnect: - try - { - socket.Connect(addr); - } - catch(SocketException ex) - { - if(interrupted(ex)) - { - goto repeatConnect; - } - - if(!connectInProgress(ex)) - { - closeSocketNoThrow(socket); - // - // Check for connectionRefused, and connectFailed - // here. - // - if(connectionRefused(ex)) - { - throw new Ice.ConnectionRefusedException("Connect refused", ex); - } - else if(connectFailed(ex)) - { - throw new Ice.ConnectFailedException("Connection failed", ex); - } - else - { - throw new Ice.SocketException(ex); - } - } - - repeatSelect: - bool ready; - bool error; - try - { - ArrayList writeList = new ArrayList(); - writeList.Add(socket); - ArrayList errorList = new ArrayList(); - errorList.Add(socket); - doSelect(null, writeList, errorList, timeout); - ready = writeList.Count != 0; - error = errorList.Count != 0; - - // - // As with C++ we need to get the SO_ERROR error - // to determine whether the connect has actually - // failed. - // - int val = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error); - if(val > 0) - { - closeSocketNoThrow(socket); - - // - // Create a Win32Exception out of this error value. Check the for refused, and - // failed. Otherwise its a plain old socket exception. - // - Win32Exception sockEx = new Win32Exception(val); - if(connectionRefused(sockEx)) - { - throw new Ice.ConnectionRefusedException("Connect refused", sockEx); - } - else if(connectFailed(sockEx)) - { - throw new Ice.ConnectFailedException("Connect failed", sockEx); - } - else - { - throw new Ice.SocketException(sockEx); - } - } - - Debug.Assert(!(ready && error)); - } - catch(SocketException e) - { - if(interrupted(e)) - { - goto repeatSelect; - } - - closeSocketNoThrow(socket); - throw new Ice.SocketException(e); - } - - if(error || !ready) - { - closeSocketNoThrow(socket); - - // - // If GetSocketOption didn't return an error and we've failed then we cannot - // distinguish between connect failed and connection refused. - // - if(error) - { - throw new Ice.ConnectFailedException("Connect failed"); - } - else - { - throw new Ice.ConnectTimeoutException("Connect timed out after " + timeout + " msec"); - } - } - } - } - - internal class AsyncConnectInfo - { - internal AsyncConnectInfo(Socket fd) - { - this.fd = fd; - this.ex = null; - this.done = false; - } - - internal Socket fd; - volatile internal Exception ex; - volatile internal bool done; - } - - private static void asyncConnectCallback(IAsyncResult ar) - { - AsyncConnectInfo info = (AsyncConnectInfo)ar.AsyncState; - lock(info) - { - try - { - info.fd.EndConnect(ar); - } - catch(Exception ex) - { - info.ex = ex; - } - finally - { - info.done = true; - Monitor.Pulse(info); - } - } - } - - public static void doConnectAsync(Socket socket, EndPoint addr, int timeout) - { + if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) + { + setSendBufferSize(socket, 64 * 1024); + } + + repeatConnect: + try + { + socket.Connect(addr); + } + catch(SocketException ex) + { + if(interrupted(ex)) + { + goto repeatConnect; + } + + if(!connectInProgress(ex)) + { + closeSocketNoThrow(socket); + // + // Check for connectionRefused, and connectFailed + // here. + // + if(connectionRefused(ex)) + { + throw new Ice.ConnectionRefusedException("Connect refused", ex); + } + else if(connectFailed(ex)) + { + throw new Ice.ConnectFailedException("Connection failed", ex); + } + else + { + throw new Ice.SocketException(ex); + } + } + + repeatSelect: + bool ready; + bool error; + try + { + ArrayList writeList = new ArrayList(); + writeList.Add(socket); + ArrayList errorList = new ArrayList(); + errorList.Add(socket); + doSelect(null, writeList, errorList, timeout); + ready = writeList.Count != 0; + error = errorList.Count != 0; + + // + // As with C++ we need to get the SO_ERROR error + // to determine whether the connect has actually + // failed. + // + int val = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error); + if(val > 0) + { + closeSocketNoThrow(socket); + + // + // Create a Win32Exception out of this error value. Check the for refused, and + // failed. Otherwise its a plain old socket exception. + // + Win32Exception sockEx = new Win32Exception(val); + if(connectionRefused(sockEx)) + { + throw new Ice.ConnectionRefusedException("Connect refused", sockEx); + } + else if(connectFailed(sockEx)) + { + throw new Ice.ConnectFailedException("Connect failed", sockEx); + } + else + { + throw new Ice.SocketException(sockEx); + } + } + + Debug.Assert(!(ready && error)); + } + catch(SocketException e) + { + if(interrupted(e)) + { + goto repeatSelect; + } + + closeSocketNoThrow(socket); + throw new Ice.SocketException(e); + } + + if(error || !ready) + { + closeSocketNoThrow(socket); + + // + // If GetSocketOption didn't return an error and we've failed then we cannot + // distinguish between connect failed and connection refused. + // + if(error) + { + throw new Ice.ConnectFailedException("Connect failed"); + } + else + { + throw new Ice.ConnectTimeoutException("Connect timed out after " + timeout + " msec"); + } + } + } + } + + internal class AsyncConnectInfo + { + internal AsyncConnectInfo(Socket fd) + { + this.fd = fd; + this.ex = null; + this.done = false; + } + + internal Socket fd; + volatile internal Exception ex; + volatile internal bool done; + } + + private static void asyncConnectCallback(IAsyncResult ar) + { + AsyncConnectInfo info = (AsyncConnectInfo)ar.AsyncState; + lock(info) + { + try + { + info.fd.EndConnect(ar); + } + catch(Exception ex) + { + info.ex = ex; + } + finally + { + info.done = true; + Monitor.Pulse(info); + } + } + } + + public static void doConnectAsync(Socket socket, EndPoint addr, int timeout) + { // // Set larger send buffer size to avoid performance problems on // WIN32. // - if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) - { - setSendBufferSize(socket, 64 * 1024); - } - - repeatConnect: - try - { - AsyncConnectInfo info = new AsyncConnectInfo(socket); - /* IAsyncResult ar = */ socket.BeginConnect(addr, new AsyncCallback(asyncConnectCallback), info); - lock(info) - { - if(!info.done) - { - if(!Monitor.Wait(info, timeout == -1 ? Timeout.Infinite : timeout)) - { - throw new Ice.ConnectTimeoutException("Connect timed out after " + timeout + " msec"); - } - } - if(info.ex != null) - { - throw info.ex; - } - } - } - catch(SocketException ex) - { - if(interrupted(ex)) - { - goto repeatConnect; - } - - closeSocketNoThrow(socket); - - // - // Check for connectionRefused, and connectFailed - // here. - // - if(connectionRefused(ex)) - { - throw new Ice.ConnectionRefusedException("Connect refused", ex); - } - else if(connectFailed(ex)) - { - throw new Ice.ConnectFailedException("Connection failed", ex); - } - else - { - throw new Ice.SocketException(ex); - } - } - } - - public static Socket doAccept(Socket socket, int timeout) - { - Socket ret = null; - - repeatAccept: - try - { - ret = socket.Accept(); - } - catch(SocketException ex) - { - if(acceptInterrupted(ex)) - { - goto repeatAccept; - } - if(wouldBlock(ex)) - { - repeatSelect: - ArrayList readList = new ArrayList(); - readList.Add(socket); - try - { - doSelect(readList, null, null, timeout); - } - catch(Win32Exception we) - { - if(interrupted(we)) - { - goto repeatSelect; - } - throw new Ice.SocketException("select failed", we); - } - catch(System.Exception se) - { - throw new Ice.SocketException("select failed", se); - } - - if(readList.Count == 0) - { - throw new Ice.TimeoutException(); - } - - goto repeatAccept; - } - } - - setTcpNoDelay(ret); - setKeepAlive(ret); - setSendBufferSize(ret, 64 * 1024); - - return ret; - } - - private static ArrayList copyList(IList list) - { - if(list == null) - { - return null; - } - return new ArrayList(list); - } - - private static void overwriteList(ArrayList from, IList to) - { - if(from != null && to != null) - { - to.Clear(); - foreach(object o in from) - { - to.Add(o); - } - } - } - - public enum PollMode { Read, Write, Error }; - - public static bool doPoll(Socket s, int timeout, PollMode mode) - { - // - // Poll() wants microseconds, so we need to deal with overflow. - // - while((timeout > System.Int32.MaxValue / 1000)) - { - if(s.Poll((System.Int32.MaxValue / 1000) * 1000, (SelectMode)mode)) - { - return true; - } - timeout -= System.Int32.MaxValue / 1000; - } - return s.Poll(timeout * 1000, (SelectMode)mode); - } - - public static void doSelect(IList checkRead, IList checkWrite, IList checkError, int milliSeconds) - { - ArrayList cr = null; - ArrayList cw = null; - ArrayList ce = null; - - if(milliSeconds < 0) - { - // - // Socket.Select() returns immediately if the timeout is < 0 (instead - // of blocking indefinitely), so we have to emulate a blocking select here. - // (Using Int32.MaxValue isn't good enough because that's only about 35 minutes.) - // - do { - cr = copyList(checkRead); - cw = copyList(checkWrite); - ce = copyList(checkError); - try - { - Socket.Select(cr, cw, ce, System.Int32.MaxValue); - } - catch(SocketException e) - { - if(interrupted(e)) - { - continue; - } - throw new Ice.SocketException(e); - } - } - while((cr == null || cr.Count == 0) && - (cw == null || cw.Count == 0) && - (ce == null || ce.Count == 0)); - overwriteList(cr, checkRead); - overwriteList(cw, checkWrite); - overwriteList(ce, checkError); - } - else - { - // - // Select() wants microseconds, so we need to deal with overflow. - // - while((milliSeconds > System.Int32.MaxValue / 1000) && - ((cr == null) || cr.Count == 0) && - ((cw == null) || cw.Count == 0) && - ((ce == null) || ce.Count == 0)) - { - cr = copyList(checkRead); - cw = copyList(checkWrite); - ce = copyList(checkError); - try - { - Socket.Select(cr, cw, ce, (System.Int32.MaxValue / 1000) * 1000); - } - catch(SocketException e) - { - if(interrupted(e)) - { - continue; - } - throw new Ice.SocketException(e); - } - milliSeconds -= System.Int32.MaxValue / 1000; - } - if(cr == null && cw == null && ce == null) - { - Socket.Select(checkRead, checkWrite, checkError, milliSeconds * 1000); - } - overwriteList(cr, checkRead); - overwriteList(cw, checkWrite); - overwriteList(ce, checkError); - } - } - - public static IPEndPoint getAddress(string host, int port) - { - int retry = 5; - - repeatGetHostByName: - try - { + if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) + { + setSendBufferSize(socket, 64 * 1024); + } + + repeatConnect: + try + { + AsyncConnectInfo info = new AsyncConnectInfo(socket); + /* IAsyncResult ar = */ socket.BeginConnect(addr, new AsyncCallback(asyncConnectCallback), info); + lock(info) + { + if(!info.done) + { + if(!Monitor.Wait(info, timeout == -1 ? Timeout.Infinite : timeout)) + { + throw new Ice.ConnectTimeoutException("Connect timed out after " + timeout + " msec"); + } + } + if(info.ex != null) + { + throw info.ex; + } + } + } + catch(SocketException ex) + { + if(interrupted(ex)) + { + goto repeatConnect; + } + + closeSocketNoThrow(socket); + + // + // Check for connectionRefused, and connectFailed + // here. + // + if(connectionRefused(ex)) + { + throw new Ice.ConnectionRefusedException("Connect refused", ex); + } + else if(connectFailed(ex)) + { + throw new Ice.ConnectFailedException("Connection failed", ex); + } + else + { + throw new Ice.SocketException(ex); + } + } + } + + public static Socket doAccept(Socket socket, int timeout) + { + Socket ret = null; + + repeatAccept: + try + { + ret = socket.Accept(); + } + catch(SocketException ex) + { + if(acceptInterrupted(ex)) + { + goto repeatAccept; + } + if(wouldBlock(ex)) + { + repeatSelect: + ArrayList readList = new ArrayList(); + readList.Add(socket); + try + { + doSelect(readList, null, null, timeout); + } + catch(Win32Exception we) + { + if(interrupted(we)) + { + goto repeatSelect; + } + throw new Ice.SocketException("select failed", we); + } + catch(System.Exception se) + { + throw new Ice.SocketException("select failed", se); + } + + if(readList.Count == 0) + { + throw new Ice.TimeoutException(); + } + + goto repeatAccept; + } + } + + setTcpNoDelay(ret); + setKeepAlive(ret); + setSendBufferSize(ret, 64 * 1024); + + return ret; + } + + private static ArrayList copyList(IList list) + { + if(list == null) + { + return null; + } + return new ArrayList(list); + } + + private static void overwriteList(ArrayList from, IList to) + { + if(from != null && to != null) + { + to.Clear(); + foreach(object o in from) + { + to.Add(o); + } + } + } + + public enum PollMode { Read, Write, Error }; + + public static bool doPoll(Socket s, int timeout, PollMode mode) + { + // + // Poll() wants microseconds, so we need to deal with overflow. + // + while((timeout > System.Int32.MaxValue / 1000)) + { + if(s.Poll((System.Int32.MaxValue / 1000) * 1000, (SelectMode)mode)) + { + return true; + } + timeout -= System.Int32.MaxValue / 1000; + } + return s.Poll(timeout * 1000, (SelectMode)mode); + } + + public static void doSelect(IList checkRead, IList checkWrite, IList checkError, int milliSeconds) + { + ArrayList cr = null; + ArrayList cw = null; + ArrayList ce = null; + + if(milliSeconds < 0) + { + // + // Socket.Select() returns immediately if the timeout is < 0 (instead + // of blocking indefinitely), so we have to emulate a blocking select here. + // (Using Int32.MaxValue isn't good enough because that's only about 35 minutes.) + // + do { + cr = copyList(checkRead); + cw = copyList(checkWrite); + ce = copyList(checkError); + try + { + Socket.Select(cr, cw, ce, System.Int32.MaxValue); + } + catch(SocketException e) + { + if(interrupted(e)) + { + continue; + } + throw new Ice.SocketException(e); + } + } + while((cr == null || cr.Count == 0) && + (cw == null || cw.Count == 0) && + (ce == null || ce.Count == 0)); + overwriteList(cr, checkRead); + overwriteList(cw, checkWrite); + overwriteList(ce, checkError); + } + else + { + // + // Select() wants microseconds, so we need to deal with overflow. + // + while((milliSeconds > System.Int32.MaxValue / 1000) && + ((cr == null) || cr.Count == 0) && + ((cw == null) || cw.Count == 0) && + ((ce == null) || ce.Count == 0)) + { + cr = copyList(checkRead); + cw = copyList(checkWrite); + ce = copyList(checkError); + try + { + Socket.Select(cr, cw, ce, (System.Int32.MaxValue / 1000) * 1000); + } + catch(SocketException e) + { + if(interrupted(e)) + { + continue; + } + throw new Ice.SocketException(e); + } + milliSeconds -= System.Int32.MaxValue / 1000; + } + if(cr == null && cw == null && ce == null) + { + Socket.Select(checkRead, checkWrite, checkError, milliSeconds * 1000); + } + overwriteList(cr, checkRead); + overwriteList(cw, checkWrite); + overwriteList(ce, checkError); + } + } + + public static IPEndPoint getAddress(string host, int port) + { + int retry = 5; + + repeatGetHostByName: + try + { try { return new IPEndPoint(IPAddress.Parse(host), port); @@ -746,276 +746,276 @@ namespace IceInternal catch (FormatException) { } - IPHostEntry e = Dns.GetHostEntry(host); - for(int i = 0; i < e.AddressList.Length; ++i) - { - if(e.AddressList[i].AddressFamily != AddressFamily.InterNetworkV6) - { - return new IPEndPoint(e.AddressList[i], port); - } - } - } - catch(Win32Exception ex) - { - if(ex.NativeErrorCode == WSATRY_AGAIN && --retry >= 0) - { - goto repeatGetHostByName; - } - Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); - e.host = host; - throw e; - } - catch(System.Exception ex) - { - Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); - e.host = host; - throw e; - } - - // - // No InterNetworkV4 address available. - // - Ice.DNSException dns = new Ice.DNSException("no IPv4 addresses found "); - dns.host = host; - throw dns; - } - - public static string getNumericHost(string hostname) - { - int retry = 5; - - repeatGetHostByName: - try - { - IPHostEntry e = Dns.GetHostEntry(hostname); - for(int i = 0; i < e.AddressList.Length; ++i) - { - if(e.AddressList[i].AddressFamily != AddressFamily.InterNetworkV6) - { - return e.AddressList[i].ToString(); - } - } - } - catch(Win32Exception ex) - { - if(ex.NativeErrorCode == WSATRY_AGAIN && --retry >= 0) - { - goto repeatGetHostByName; - } - Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); - e.host = hostname; - throw e; - } - catch(System.Exception ex) - { - Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); - e.host = hostname; - throw e; - } - - // - // No InterNetworkV4 address available. - // - Ice.DNSException dns = new Ice.DNSException("no IPv4 addresses found"); - dns.host = hostname; - throw dns; - } - - public static string[] getLocalHosts() - { - ArrayList hosts; - - int retry = 5; - - repeatGetHostByName: - try - { - IPHostEntry e = Dns.GetHostEntry(Dns.GetHostName()); - hosts = new ArrayList(); - for(int i = 0; i < e.AddressList.Length; ++i) - { - if(e.AddressList[i].AddressFamily != AddressFamily.InterNetworkV6) - { - hosts.Add(e.AddressList[i].ToString()); - } - } - hosts.Add(IPAddress.Loopback.ToString()); - } - catch(Win32Exception ex) - { - if(ex.NativeErrorCode == WSATRY_AGAIN && --retry >= 0) - { - goto repeatGetHostByName; - } - Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); - e.host = "0.0.0.0"; - throw e; - } - catch(System.Exception ex) - { - Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); - e.host = "0.0.0.0"; - throw e; - } - - return (string[])hosts.ToArray(typeof(string)); - } - - public sealed class SocketPair - { - public Socket source; - public Socket sink; - - public SocketPair() - { - sink = createSocket(false); - Socket listener = createSocket(false); - - doBind(listener, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0)); - doListen(listener, 1); - doConnect(sink, listener.LocalEndPoint, 1000); - try - { - source = doAccept(listener, -1); - } - catch(Ice.SocketException) - { - try - { - sink.Close(); - } - catch(System.Exception) - { - // ignore - } - throw; - } - finally - { - try - { - listener.Close(); - } - catch(System.Exception) - { - } - } - } - } - - public static SocketPair createPipe() - { - return new SocketPair(); - } - - [StructLayout(LayoutKind.Sequential)] - private struct in_addr - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] - public byte[] sin_addr; - } - - [StructLayout(LayoutKind.Sequential)] - private struct sockaddr - { - public short sin_family; - public ushort sin_port; - public in_addr sin_addr; - [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)] - public byte[] sin_zero; - } - - [DllImport("wsock32.dll")] - private static extern int getsockname(IntPtr s, ref sockaddr name, ref int namelen); - - [DllImport("wsock32.dll")] - private static extern int getpeername(IntPtr s, ref sockaddr name, ref int namelen); - - [DllImport("ws2_32.dll")] - private static extern IntPtr inet_ntoa(in_addr a); - - [DllImport("ws2_32.dll")] - private static extern ushort ntohs(ushort netshort); - - public static string fdToString(Socket socket) - { - if(socket == null) - { - return "<closed>"; - } - - // - // .Net BUG: The LocalEndPoint and RemoteEndPoint properties - // are null for a socket that was connected in non-blocking - // mode. The only way to make this work is to step down to - // the native API and use platform invoke :-( - // - IPEndPoint localEndpoint; - IPEndPoint remoteEndpoint; - if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) - { - sockaddr addr = new sockaddr(); - int addrLen = 16; - - if(getsockname(socket.Handle, ref addr, ref addrLen) != 0) - { - throw new Ice.SyscallException("getsockname call failed"); - } - string ip = Marshal.PtrToStringAnsi(inet_ntoa(addr.sin_addr)); - int port = ntohs(addr.sin_port); - localEndpoint = new IPEndPoint(IPAddress.Parse(ip), port); - - remoteEndpoint = null; - if(getpeername(socket.Handle, ref addr, ref addrLen) == 0) - { - ip = Marshal.PtrToStringAnsi(inet_ntoa(addr.sin_addr)); - port = ntohs(addr.sin_port); - remoteEndpoint = new IPEndPoint(IPAddress.Parse(ip), port); - } - } - else - { - try - { - localEndpoint = (IPEndPoint)socket.LocalEndPoint; - } - catch(SocketException ex) - { - throw new Ice.SocketException(ex); - } - - try - { - remoteEndpoint = (IPEndPoint)socket.RemoteEndPoint; - } - catch(SocketException) - { - remoteEndpoint = null; - } - } - - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("local address = " + localEndpoint.Address); - s.Append(":" + localEndpoint.Port); - - if(remoteEndpoint == null) - { - s.Append("\nremote address = <not connected>"); - } - else - { - s.Append("\nremote address = " + IPAddress.Parse(remoteEndpoint.Address.ToString())); - s.Append(":" + remoteEndpoint.Port.ToString()); - } - - return s.ToString(); - } - - public static string - addrToString(EndPoint addr) - { - return addr.ToString(); - } + IPHostEntry e = Dns.GetHostEntry(host); + for(int i = 0; i < e.AddressList.Length; ++i) + { + if(e.AddressList[i].AddressFamily != AddressFamily.InterNetworkV6) + { + return new IPEndPoint(e.AddressList[i], port); + } + } + } + catch(Win32Exception ex) + { + if(ex.NativeErrorCode == WSATRY_AGAIN && --retry >= 0) + { + goto repeatGetHostByName; + } + Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); + e.host = host; + throw e; + } + catch(System.Exception ex) + { + Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); + e.host = host; + throw e; + } + + // + // No InterNetworkV4 address available. + // + Ice.DNSException dns = new Ice.DNSException("no IPv4 addresses found "); + dns.host = host; + throw dns; + } + + public static string getNumericHost(string hostname) + { + int retry = 5; + + repeatGetHostByName: + try + { + IPHostEntry e = Dns.GetHostEntry(hostname); + for(int i = 0; i < e.AddressList.Length; ++i) + { + if(e.AddressList[i].AddressFamily != AddressFamily.InterNetworkV6) + { + return e.AddressList[i].ToString(); + } + } + } + catch(Win32Exception ex) + { + if(ex.NativeErrorCode == WSATRY_AGAIN && --retry >= 0) + { + goto repeatGetHostByName; + } + Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); + e.host = hostname; + throw e; + } + catch(System.Exception ex) + { + Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); + e.host = hostname; + throw e; + } + + // + // No InterNetworkV4 address available. + // + Ice.DNSException dns = new Ice.DNSException("no IPv4 addresses found"); + dns.host = hostname; + throw dns; + } + + public static string[] getLocalHosts() + { + ArrayList hosts; + + int retry = 5; + + repeatGetHostByName: + try + { + IPHostEntry e = Dns.GetHostEntry(Dns.GetHostName()); + hosts = new ArrayList(); + for(int i = 0; i < e.AddressList.Length; ++i) + { + if(e.AddressList[i].AddressFamily != AddressFamily.InterNetworkV6) + { + hosts.Add(e.AddressList[i].ToString()); + } + } + hosts.Add(IPAddress.Loopback.ToString()); + } + catch(Win32Exception ex) + { + if(ex.NativeErrorCode == WSATRY_AGAIN && --retry >= 0) + { + goto repeatGetHostByName; + } + Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); + e.host = "0.0.0.0"; + throw e; + } + catch(System.Exception ex) + { + Ice.DNSException e = new Ice.DNSException("address lookup failed", ex); + e.host = "0.0.0.0"; + throw e; + } + + return (string[])hosts.ToArray(typeof(string)); + } + + public sealed class SocketPair + { + public Socket source; + public Socket sink; + + public SocketPair() + { + sink = createSocket(false); + Socket listener = createSocket(false); + + doBind(listener, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0)); + doListen(listener, 1); + doConnect(sink, listener.LocalEndPoint, 1000); + try + { + source = doAccept(listener, -1); + } + catch(Ice.SocketException) + { + try + { + sink.Close(); + } + catch(System.Exception) + { + // ignore + } + throw; + } + finally + { + try + { + listener.Close(); + } + catch(System.Exception) + { + } + } + } + } + + public static SocketPair createPipe() + { + return new SocketPair(); + } + + [StructLayout(LayoutKind.Sequential)] + private struct in_addr + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] + public byte[] sin_addr; + } + + [StructLayout(LayoutKind.Sequential)] + private struct sockaddr + { + public short sin_family; + public ushort sin_port; + public in_addr sin_addr; + [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)] + public byte[] sin_zero; + } + + [DllImport("wsock32.dll")] + private static extern int getsockname(IntPtr s, ref sockaddr name, ref int namelen); + + [DllImport("wsock32.dll")] + private static extern int getpeername(IntPtr s, ref sockaddr name, ref int namelen); + + [DllImport("ws2_32.dll")] + private static extern IntPtr inet_ntoa(in_addr a); + + [DllImport("ws2_32.dll")] + private static extern ushort ntohs(ushort netshort); + + public static string fdToString(Socket socket) + { + if(socket == null) + { + return "<closed>"; + } + + // + // .Net BUG: The LocalEndPoint and RemoteEndPoint properties + // are null for a socket that was connected in non-blocking + // mode. The only way to make this work is to step down to + // the native API and use platform invoke :-( + // + IPEndPoint localEndpoint; + IPEndPoint remoteEndpoint; + if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) + { + sockaddr addr = new sockaddr(); + int addrLen = 16; + + if(getsockname(socket.Handle, ref addr, ref addrLen) != 0) + { + throw new Ice.SyscallException("getsockname call failed"); + } + string ip = Marshal.PtrToStringAnsi(inet_ntoa(addr.sin_addr)); + int port = ntohs(addr.sin_port); + localEndpoint = new IPEndPoint(IPAddress.Parse(ip), port); + + remoteEndpoint = null; + if(getpeername(socket.Handle, ref addr, ref addrLen) == 0) + { + ip = Marshal.PtrToStringAnsi(inet_ntoa(addr.sin_addr)); + port = ntohs(addr.sin_port); + remoteEndpoint = new IPEndPoint(IPAddress.Parse(ip), port); + } + } + else + { + try + { + localEndpoint = (IPEndPoint)socket.LocalEndPoint; + } + catch(SocketException ex) + { + throw new Ice.SocketException(ex); + } + + try + { + remoteEndpoint = (IPEndPoint)socket.RemoteEndPoint; + } + catch(SocketException) + { + remoteEndpoint = null; + } + } + + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("local address = " + localEndpoint.Address); + s.Append(":" + localEndpoint.Port); + + if(remoteEndpoint == null) + { + s.Append("\nremote address = <not connected>"); + } + else + { + s.Append("\nremote address = " + IPAddress.Parse(remoteEndpoint.Address.ToString())); + s.Append(":" + remoteEndpoint.Port.ToString()); + } + + return s.ToString(); + } + + public static string + addrToString(EndPoint addr) + { + return addr.ToString(); + } } } |