PageRenderTime 60ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/cs/src/Ice/Network.cs

https://bitbucket.org/cleto/zeroc-ice-package
C# | 1443 lines | 1189 code | 107 blank | 147 comment | 217 complexity | fa80e81bdaf4a49a8e3e3adc19cc3aae MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, GPL-2.0, BSD-3-Clause
  1. // **********************************************************************
  2. //
  3. // Copyright (c) 2003-2013 ZeroC, Inc. All rights reserved.
  4. //
  5. // This copy of Ice is licensed to you under the terms described in the
  6. // ICE_LICENSE file included in this distribution.
  7. //
  8. // **********************************************************************
  9. namespace IceInternal
  10. {
  11. using System;
  12. using System.Collections;
  13. using System.Collections.Generic;
  14. using System.ComponentModel;
  15. using System.Diagnostics;
  16. using System.Net;
  17. #if !COMPACT && !UNITY
  18. using System.Net.NetworkInformation;
  19. #endif
  20. using System.Net.Sockets;
  21. using System.Runtime.InteropServices;
  22. using System.Threading;
  23. using System.Globalization;
  24. public interface NetworkProxy
  25. {
  26. //
  27. // Write the connection request on the connection established
  28. // with the network proxy server. This is called right after
  29. // the connection establishment succeeds.
  30. //
  31. void beginWriteConnectRequest(EndPoint endpoint, Buffer buf);
  32. void endWriteConnectRequest(Buffer buf);
  33. //
  34. // Once the connection request has been sent, this is called
  35. // to prepare and read the response from the proxy server.
  36. //
  37. void beginReadConnectRequestResponse(Buffer buf);
  38. void endReadConnectRequestResponse(Buffer buf);
  39. #if !SILVERLIGHT
  40. //
  41. // If the proxy host needs to be resolved, this should return
  42. // a new NetworkProxy containing the IP address of the proxy.
  43. // This is called from the endpoint host resolver thread, so
  44. // it's safe if this this method blocks.
  45. //
  46. NetworkProxy resolveHost();
  47. #endif
  48. //
  49. // Returns the IP address of the network proxy. This method
  50. // must not block. It's only called on a network proxy object
  51. // returned by resolveHost().
  52. //
  53. EndPoint getAddress();
  54. //
  55. // Returns the name of the proxy, used for tracing purposes.
  56. //
  57. string getName();
  58. }
  59. public sealed class SOCKSNetworkProxy : NetworkProxy
  60. {
  61. public SOCKSNetworkProxy(string host, int port)
  62. {
  63. #if SILVERLIGHT
  64. _address = new DnsEndPoint(host, port, AddressFamily.InterNetwork);
  65. #else
  66. _host = host;
  67. _port = port;
  68. #endif
  69. }
  70. private SOCKSNetworkProxy(EndPoint address)
  71. {
  72. _address = address;
  73. }
  74. public void beginWriteConnectRequest(EndPoint endpoint, Buffer buf)
  75. {
  76. if(!(endpoint is IPEndPoint))
  77. {
  78. throw new Ice.FeatureNotSupportedException("SOCKS4 does not support domain names");
  79. }
  80. else if(endpoint.AddressFamily != AddressFamily.InterNetwork)
  81. {
  82. throw new Ice.FeatureNotSupportedException("SOCKS4 only supports IPv4 addresses");
  83. }
  84. //
  85. // SOCKS connect request
  86. //
  87. IPEndPoint addr = (IPEndPoint)endpoint;
  88. buf.resize(9, false);
  89. ByteBuffer.ByteOrder order = buf.b.order();
  90. buf.b.order(ByteBuffer.ByteOrder.BIG_ENDIAN); // Network byte order.
  91. buf.b.position(0);
  92. buf.b.put(0x04); // SOCKS version 4.
  93. buf.b.put(0x01); // Command, establish a TCP/IP stream connection
  94. buf.b.putShort((short)addr.Port); // Port
  95. buf.b.put(addr.Address.GetAddressBytes()); // IPv4 address
  96. buf.b.put(0x00); // User ID.
  97. buf.b.position(0);
  98. buf.b.limit(buf.size());
  99. buf.b.order(order);
  100. }
  101. public void endWriteConnectRequest(Buffer buf)
  102. {
  103. buf.reset();
  104. }
  105. public void beginReadConnectRequestResponse(Buffer buf)
  106. {
  107. //
  108. // Read the SOCKS4 response whose size is 8 bytes.
  109. //
  110. buf.resize(8, true);
  111. buf.b.position(0);
  112. }
  113. public void endReadConnectRequestResponse(Buffer buf)
  114. {
  115. buf.b.position(0);
  116. byte b1 = buf.b.get();
  117. byte b2 = buf.b.get();
  118. if(b1 != 0x00 || b2 != 0x5a)
  119. {
  120. throw new Ice.ConnectFailedException();
  121. }
  122. buf.reset();
  123. }
  124. #if !SILVERLIGHT
  125. public NetworkProxy resolveHost()
  126. {
  127. Debug.Assert(_host != null);
  128. return new SOCKSNetworkProxy(Network.getAddresses(_host,
  129. _port,
  130. Network.EnableIPv4,
  131. Ice.EndpointSelectionType.Random,
  132. false,
  133. true)[0]);
  134. }
  135. #endif
  136. public EndPoint getAddress()
  137. {
  138. Debug.Assert(_address != null); // Host must be resolved.
  139. return _address;
  140. }
  141. public string getName()
  142. {
  143. return "SOCKS";
  144. }
  145. #if !SILVERLIGHT
  146. private readonly string _host;
  147. private readonly int _port;
  148. #endif
  149. private readonly EndPoint _address;
  150. }
  151. public sealed class Network
  152. {
  153. // ProtocolSupport
  154. public const int EnableIPv4 = 0;
  155. public const int EnableIPv6 = 1;
  156. public const int EnableBoth = 2;
  157. #if COMPACT
  158. public static SocketError socketErrorCode(SocketException ex)
  159. {
  160. return (SocketError)ex.ErrorCode;
  161. }
  162. #else
  163. public static SocketError socketErrorCode(SocketException ex)
  164. {
  165. return ex.SocketErrorCode;
  166. }
  167. #endif
  168. #if COMPACT
  169. //
  170. // SocketError enumeration isn't available with Silverlight
  171. //
  172. public enum SocketError
  173. {
  174. Interrupted = 10004, // A blocking Socket call was canceled.
  175. //AccessDenied =10013, // An attempt was made to access a Socket in a way that is forbidden by its access permissions.
  176. Fault = 10014, // An invalid pointer address was detected by the underlying socket provider.
  177. InvalidArgument = 10022, // An invalid argument was supplied to a Socket member.
  178. TooManyOpenSockets = 10024, // There are too many open sockets in the underlying socket provider.
  179. WouldBlock = 10035, // An operation on a nonblocking socket cannot be completed immediately.
  180. InProgress = 10036, // A blocking operation is in progress.
  181. //AlreadyInProgress = 10037, // The nonblocking Socket already has an operation in progress.
  182. //NotSocket = 10038, // A Socket operation was attempted on a non-socket.
  183. //DestinationAddressRequired = 10039, // A required address was omitted from an operation on a Socket.
  184. MessageSize = 10040, // The datagram is too long.
  185. //ProtocolType = 10041, // The protocol type is incorrect for this Socket.
  186. //ProtocolOption = 10042, // An unknown, invalid, or unsupported option or level was used with a Socket.
  187. //ProtocolNotSupported = 10043, // The protocol is not implemented or has not been configured.
  188. //SocketNotSupported = 10044, // The support for the specified socket type does not exist in this address family.
  189. //OperationNotSupported = 10045, // The address family is not supported by the protocol family.
  190. //ProtocolFamilyNotSupported = 10046, // The protocol family is not implemented or has not been configured.
  191. //AddressFamilyNotSupported = 10047, // The address family specified is not supported.
  192. //AddressAlreadyInUse = 10048, // Only one use of an address is normally permitted.
  193. //AddressNotAvailable = 10049, // The selected IP address is not valid in this context.
  194. NetworkDown = 10050, // The network is not available.
  195. NetworkUnreachable = 10051, // No route to the remote host exists.
  196. NetworkReset = 10052, // The application tried to set KeepAlive on a connection that has already timed out.
  197. ConnectionAborted = 10053, // The connection was aborted by the .NET Framework or the underlying socket provider.
  198. ConnectionReset = 10054, // The connection was reset by the remote peer.
  199. NoBufferSpaceAvailable = 10055, // No free buffer space is available for a Socket operation.
  200. //IsConnected = 10056, // The Socket is already connected.
  201. NotConnected = 10057, // The application tried to send or receive data, and the Socket is not connected.
  202. Shutdown = 10058, // A request to send or receive data was disallowed because the Socket has already been closed.
  203. TimedOut = 10060, // The connection attempt timed out, or the connected host has failed to respond.
  204. ConnectionRefused = 10061, // The remote host is actively refusing a connection.
  205. //HostDown = 10064, // The operation failed because the remote host is down.
  206. HostUnreachable = 10065, // There is no network route to the specified host.
  207. //ProcessLimit = 10067, // Too many processes are using the underlying socket provider.
  208. //SystemNotReady = 10091, // The network subsystem is unavailable.
  209. //VersionNotSupported = 10092, // The version of the underlying socket provider is out of range.
  210. //NotInitialized = 10093, // The underlying socket provider has not been initialized.
  211. //Disconnecting = 10101, // A graceful shutdown is in progress.
  212. //TypeNotFound = 10109, // The specified class was not found.
  213. //HostNotFound = 11001, // No such host is known. The name is not an official host name or alias.
  214. TryAgain = 11002, // The name of the host could not be resolved. Try again later.
  215. //NoRecovery = 11003, // The error is unrecoverable or the requested database cannot be located.
  216. //NoData = 11004, // The requested name or IP address was not found on the name server.
  217. //IOPending = 997, // The application has initiated an overlapped operation that cannot be completed immediately.
  218. OperationAborted =995 // The overlapped operation was aborted due to the closure of the Socket.
  219. }
  220. #endif
  221. public static bool interrupted(SocketException ex)
  222. {
  223. return socketErrorCode(ex) == SocketError.Interrupted;
  224. }
  225. public static bool acceptInterrupted(SocketException ex)
  226. {
  227. if(interrupted(ex))
  228. {
  229. return true;
  230. }
  231. SocketError error = socketErrorCode(ex);
  232. return error == SocketError.ConnectionAborted ||
  233. error == SocketError.ConnectionReset ||
  234. error == SocketError.TimedOut;
  235. }
  236. public static bool noBuffers(SocketException ex)
  237. {
  238. SocketError error = socketErrorCode(ex);
  239. return error == SocketError.NoBufferSpaceAvailable ||
  240. error == SocketError.Fault;
  241. }
  242. public static bool wouldBlock(SocketException ex)
  243. {
  244. return socketErrorCode(ex) == SocketError.WouldBlock;
  245. }
  246. public static bool connectFailed(SocketException ex)
  247. {
  248. SocketError error = socketErrorCode(ex);
  249. return error == SocketError.ConnectionRefused ||
  250. error == SocketError.TimedOut ||
  251. error == SocketError.NetworkUnreachable ||
  252. error == SocketError.HostUnreachable ||
  253. error == SocketError.ConnectionReset ||
  254. error == SocketError.Shutdown ||
  255. error == SocketError.ConnectionAborted ||
  256. error == SocketError.NetworkDown;
  257. }
  258. public static bool connectInProgress(SocketException ex)
  259. {
  260. SocketError error = socketErrorCode(ex);
  261. return error == SocketError.WouldBlock ||
  262. error == SocketError.InProgress;
  263. }
  264. public static bool connectionLost(SocketException ex)
  265. {
  266. SocketError error = socketErrorCode(ex);
  267. return error == SocketError.ConnectionReset ||
  268. error == SocketError.Shutdown ||
  269. error == SocketError.ConnectionAborted ||
  270. error == SocketError.NetworkDown ||
  271. error == SocketError.NetworkReset;
  272. }
  273. public static bool connectionLost(System.IO.IOException ex)
  274. {
  275. //
  276. // In some cases the IOException has an inner exception that we can pass directly
  277. // to the other overloading of connectionLost().
  278. //
  279. if(ex.InnerException != null && ex.InnerException is SocketException)
  280. {
  281. return connectionLost(ex.InnerException as SocketException);
  282. }
  283. //
  284. // In other cases the IOException has no inner exception. We could examine the
  285. // exception's message, but that is fragile due to localization issues. We
  286. // resort to extracting the value of the protected HResult member via reflection.
  287. //
  288. int hr = (int)ex.GetType().GetProperty("HResult",
  289. System.Reflection.BindingFlags.Instance |
  290. System.Reflection.BindingFlags.NonPublic |
  291. System.Reflection.BindingFlags.Public).GetValue(ex, null);
  292. //
  293. // This value corresponds to the following errors:
  294. //
  295. // "Authentication failed because the remote party has closed the transport stream"
  296. //
  297. if(hr == -2146232800)
  298. {
  299. return true;
  300. }
  301. return false;
  302. }
  303. public static bool connectionRefused(SocketException ex)
  304. {
  305. return socketErrorCode(ex) == SocketError.ConnectionRefused;
  306. }
  307. public static bool notConnected(SocketException ex)
  308. {
  309. // BUGFIX: SocketError.InvalidArgument because shutdown() under OS X returns EINVAL
  310. // if the server side is gone.
  311. // BUGFIX: shutdown() under Vista might return SocketError.ConnectionReset
  312. SocketError error = socketErrorCode(ex);
  313. return error == SocketError.NotConnected ||
  314. error == SocketError.InvalidArgument ||
  315. error == SocketError.ConnectionReset;
  316. }
  317. public static bool recvTruncated(SocketException ex)
  318. {
  319. return socketErrorCode(ex) == SocketError.MessageSize;
  320. }
  321. public static bool operationAborted(SocketException ex)
  322. {
  323. return socketErrorCode(ex) == SocketError.OperationAborted;
  324. }
  325. public static bool timeout(System.IO.IOException ex)
  326. {
  327. //
  328. // TODO: Instead of testing for an English substring, we need to examine the inner
  329. // exception (if there is one).
  330. //
  331. return ex.Message.IndexOf("period of time", StringComparison.Ordinal) >= 0;
  332. }
  333. public static bool noMoreFds(System.Exception ex)
  334. {
  335. try
  336. {
  337. return ex != null && socketErrorCode((SocketException)ex) == SocketError.TooManyOpenSockets;
  338. }
  339. catch(InvalidCastException)
  340. {
  341. return false;
  342. }
  343. }
  344. public static bool isMulticast(IPEndPoint addr)
  345. {
  346. #if COMPACT
  347. string ip = addr.Address.ToString().ToUpper();
  348. #else
  349. string ip = addr.Address.ToString().ToUpperInvariant();
  350. #endif
  351. if(addr.AddressFamily == AddressFamily.InterNetwork)
  352. {
  353. char[] splitChars = { '.' };
  354. string[] arr = ip.Split(splitChars);
  355. try
  356. {
  357. int i = System.Int32.Parse(arr[0], CultureInfo.InvariantCulture);
  358. if(i >= 223 && i <= 239)
  359. {
  360. return true;
  361. }
  362. }
  363. catch(System.FormatException)
  364. {
  365. return false;
  366. }
  367. }
  368. else // AddressFamily.InterNetworkV6
  369. {
  370. if(ip.StartsWith("FF", StringComparison.Ordinal))
  371. {
  372. return true;
  373. }
  374. }
  375. return false;
  376. }
  377. public static Socket createSocket(bool udp, AddressFamily family)
  378. {
  379. Socket socket;
  380. try
  381. {
  382. if(udp)
  383. {
  384. socket = new Socket(family, SocketType.Dgram, ProtocolType.Udp);
  385. }
  386. else
  387. {
  388. socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
  389. }
  390. }
  391. catch(SocketException ex)
  392. {
  393. throw new Ice.SocketException(ex);
  394. }
  395. catch(ArgumentException ex)
  396. {
  397. throw new Ice.SocketException(ex);
  398. }
  399. if(!udp)
  400. {
  401. try
  402. {
  403. setTcpNoDelay(socket);
  404. #if !SILVERLIGHT
  405. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
  406. #endif
  407. }
  408. catch(SocketException ex)
  409. {
  410. closeSocketNoThrow(socket);
  411. throw new Ice.SocketException(ex);
  412. }
  413. }
  414. return socket;
  415. }
  416. public static Socket createServerSocket(bool udp, AddressFamily family, int protocol)
  417. {
  418. Socket socket = createSocket(udp, family);
  419. # if !COMPACT && !UNITY && !__MonoCS__ && !SILVERLIGHT
  420. if(family == AddressFamily.InterNetworkV6 && protocol != EnableIPv4)
  421. {
  422. try
  423. {
  424. int flag = protocol == EnableIPv6 ? 1 : 0;
  425. socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, flag);
  426. }
  427. catch(SocketException ex)
  428. {
  429. closeSocketNoThrow(socket);
  430. throw new Ice.SocketException(ex);
  431. }
  432. }
  433. #endif
  434. return socket;
  435. }
  436. public static void closeSocketNoThrow(Socket socket)
  437. {
  438. if(socket == null)
  439. {
  440. return;
  441. }
  442. try
  443. {
  444. socket.Close();
  445. }
  446. catch(SocketException)
  447. {
  448. // Ignore
  449. }
  450. }
  451. public static void closeSocket(Socket socket)
  452. {
  453. if(socket == null)
  454. {
  455. return;
  456. }
  457. try
  458. {
  459. socket.Close();
  460. }
  461. catch(SocketException ex)
  462. {
  463. throw new Ice.SocketException(ex);
  464. }
  465. }
  466. public static void setTcpNoDelay(Socket socket)
  467. {
  468. try
  469. {
  470. #if SILVERLIGHT
  471. socket.NoDelay = true;
  472. #else
  473. socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
  474. #endif
  475. }
  476. catch(System.Exception ex)
  477. {
  478. closeSocketNoThrow(socket);
  479. throw new Ice.SocketException(ex);
  480. }
  481. }
  482. #if !SILVERLIGHT
  483. public static void setBlock(Socket socket, bool block)
  484. {
  485. try
  486. {
  487. socket.Blocking = block;
  488. }
  489. catch(SocketException ex)
  490. {
  491. closeSocketNoThrow(socket);
  492. throw new Ice.SocketException(ex);
  493. }
  494. }
  495. public static void setKeepAlive(Socket socket)
  496. {
  497. try
  498. {
  499. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
  500. }
  501. catch(System.Exception ex)
  502. {
  503. closeSocketNoThrow(socket);
  504. throw new Ice.SocketException(ex);
  505. }
  506. }
  507. #endif
  508. public static void setSendBufferSize(Socket socket, int sz)
  509. {
  510. try
  511. {
  512. #if SILVERLIGHT
  513. socket.SendBufferSize = sz;
  514. #else
  515. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, sz);
  516. #endif
  517. }
  518. catch(SocketException ex)
  519. {
  520. closeSocketNoThrow(socket);
  521. throw new Ice.SocketException(ex);
  522. }
  523. }
  524. public static int getSendBufferSize(Socket socket)
  525. {
  526. int sz;
  527. try
  528. {
  529. #if SILVERLIGHT
  530. sz = socket.SendBufferSize;
  531. #else
  532. sz = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer);
  533. #endif
  534. }
  535. catch(SocketException ex)
  536. {
  537. closeSocketNoThrow(socket);
  538. throw new Ice.SocketException(ex);
  539. }
  540. return sz;
  541. }
  542. public static void setRecvBufferSize(Socket socket, int sz)
  543. {
  544. try
  545. {
  546. #if SILVERLIGHT
  547. socket.ReceiveBufferSize = sz;
  548. #else
  549. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, sz);
  550. #endif
  551. }
  552. catch(SocketException ex)
  553. {
  554. closeSocketNoThrow(socket);
  555. throw new Ice.SocketException(ex);
  556. }
  557. }
  558. public static int getRecvBufferSize(Socket socket)
  559. {
  560. int sz = 0;
  561. try
  562. {
  563. #if SILVERLIGHT
  564. sz = socket.ReceiveBufferSize;
  565. #else
  566. sz = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer);
  567. #endif
  568. }
  569. catch(SocketException ex)
  570. {
  571. closeSocketNoThrow(socket);
  572. throw new Ice.SocketException(ex);
  573. }
  574. return sz;
  575. }
  576. #if !SILVERLIGHT
  577. public static void setReuseAddress(Socket socket, bool reuse)
  578. {
  579. try
  580. {
  581. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, reuse ? 1 : 0);
  582. }
  583. catch(SocketException ex)
  584. {
  585. closeSocketNoThrow(socket);
  586. throw new Ice.SocketException(ex);
  587. }
  588. }
  589. public static void setMcastGroup(Socket socket, IPAddress group, string iface)
  590. {
  591. try
  592. {
  593. if(group.AddressFamily == AddressFamily.InterNetwork)
  594. {
  595. IPAddress ifaceAddr = IPAddress.Any;
  596. if(iface.Length != 0)
  597. {
  598. ifaceAddr = getInterfaceAddress(iface);
  599. if(ifaceAddr == IPAddress.Any)
  600. {
  601. ifaceAddr = ((IPEndPoint)getAddressForServer(iface, 0, EnableIPv4, false)).Address;
  602. }
  603. }
  604. socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
  605. new MulticastOption(group, ifaceAddr));
  606. }
  607. else
  608. {
  609. int ifaceIndex = 0;
  610. if(iface.Length != 0)
  611. {
  612. ifaceIndex = getInterfaceIndex(iface);
  613. if(ifaceIndex == 0)
  614. {
  615. try
  616. {
  617. ifaceIndex = System.Int32.Parse(iface, CultureInfo.InvariantCulture);
  618. }
  619. catch(System.FormatException ex)
  620. {
  621. closeSocketNoThrow(socket);
  622. throw new Ice.SocketException(ex);
  623. }
  624. }
  625. }
  626. socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership,
  627. new IPv6MulticastOption(group, ifaceIndex));
  628. }
  629. }
  630. catch(SocketException ex)
  631. {
  632. closeSocketNoThrow(socket);
  633. throw new Ice.SocketException(ex);
  634. }
  635. }
  636. #endif
  637. public static void setMcastTtl(Socket socket, int ttl, AddressFamily family)
  638. {
  639. try
  640. {
  641. #if SILVERLIGHT
  642. socket.Ttl = (short)ttl;
  643. #else
  644. if(family == AddressFamily.InterNetwork)
  645. {
  646. socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, ttl);
  647. }
  648. else
  649. {
  650. socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive, ttl);
  651. }
  652. #endif
  653. }
  654. catch(SocketException ex)
  655. {
  656. closeSocketNoThrow(socket);
  657. throw new Ice.SocketException(ex);
  658. }
  659. }
  660. #if !SILVERLIGHT
  661. public static IPEndPoint doBind(Socket socket, EndPoint addr)
  662. {
  663. try
  664. {
  665. socket.Bind(addr);
  666. return (IPEndPoint)socket.LocalEndPoint;
  667. }
  668. catch(SocketException ex)
  669. {
  670. closeSocketNoThrow(socket);
  671. throw new Ice.SocketException(ex);
  672. }
  673. }
  674. public static void doListen(Socket socket, int backlog)
  675. {
  676. repeatListen:
  677. try
  678. {
  679. socket.Listen(backlog);
  680. }
  681. catch(SocketException ex)
  682. {
  683. if(interrupted(ex))
  684. {
  685. goto repeatListen;
  686. }
  687. closeSocketNoThrow(socket);
  688. throw new Ice.SocketException(ex);
  689. }
  690. }
  691. #endif
  692. #if !SILVERLIGHT
  693. public static bool doConnect(Socket fd, EndPoint addr)
  694. {
  695. repeatConnect:
  696. try
  697. {
  698. //
  699. // Even though we are on the client side, the call to Bind()
  700. // is necessary to work around a .NET bug: if a socket is
  701. // connected non-blocking, the LocalEndPoint and RemoteEndPoint
  702. // properties are null. The call to Bind() fixes this.
  703. //
  704. IPAddress any = fd.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any;
  705. fd.Bind(new IPEndPoint(any, 0));
  706. IAsyncResult result = fd.BeginConnect(addr, null, null);
  707. if(!result.CompletedSynchronously)
  708. {
  709. return false;
  710. }
  711. fd.EndConnect(result);
  712. }
  713. catch(SocketException ex)
  714. {
  715. if(interrupted(ex))
  716. {
  717. goto repeatConnect;
  718. }
  719. closeSocketNoThrow(fd);
  720. if(connectionRefused(ex))
  721. {
  722. throw new Ice.ConnectionRefusedException(ex);
  723. }
  724. else
  725. {
  726. throw new Ice.ConnectFailedException(ex);
  727. }
  728. }
  729. //
  730. // On Windows, we need to set the socket's blocking status again
  731. // after the asynchronous connect. Seems like a bug in .NET.
  732. //
  733. setBlock(fd, fd.Blocking);
  734. if(AssemblyUtil.platform_ == AssemblyUtil.Platform.NonWindows)
  735. {
  736. //
  737. // Prevent self connect (self connect happens on Linux when a client tries to connect to
  738. // a server which was just deactivated if the client socket re-uses the same ephemeral
  739. // port as the server).
  740. //
  741. if(addr.Equals(getLocalAddress(fd)))
  742. {
  743. throw new Ice.ConnectionRefusedException();
  744. }
  745. }
  746. return true;
  747. }
  748. public static IAsyncResult doConnectAsync(Socket fd, EndPoint addr, AsyncCallback callback, object state)
  749. {
  750. //
  751. // NOTE: It's the caller's responsability to close the socket upon
  752. // failure to connect. The socket isn't closed by this method.
  753. //
  754. repeatConnect:
  755. try
  756. {
  757. //
  758. // Even though we are on the client side, the call to Bind()
  759. // is necessary to work around a .NET bug: if a socket is
  760. // connected non-blocking, the LocalEndPoint and RemoteEndPoint
  761. // properties are null. The call to Bind() fixes this.
  762. //
  763. IPAddress any = fd.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any;
  764. fd.Bind(new IPEndPoint(any, 0));
  765. return fd.BeginConnect(addr,
  766. delegate(IAsyncResult result)
  767. {
  768. if(!result.CompletedSynchronously)
  769. {
  770. callback(result.AsyncState);
  771. }
  772. }, state);
  773. }
  774. catch(SocketException ex)
  775. {
  776. if(interrupted(ex))
  777. {
  778. goto repeatConnect;
  779. }
  780. if(connectionRefused(ex))
  781. {
  782. throw new Ice.ConnectionRefusedException(ex);
  783. }
  784. else
  785. {
  786. throw new Ice.ConnectFailedException(ex);
  787. }
  788. }
  789. }
  790. public static void doFinishConnectAsync(Socket fd, IAsyncResult result)
  791. {
  792. //
  793. // NOTE: It's the caller's responsability to close the socket upon
  794. // failure to connect. The socket isn't closed by this method.
  795. //
  796. try
  797. {
  798. fd.EndConnect(result);
  799. }
  800. catch(SocketException ex)
  801. {
  802. if(connectionRefused(ex))
  803. {
  804. throw new Ice.ConnectionRefusedException(ex);
  805. }
  806. else
  807. {
  808. throw new Ice.ConnectFailedException(ex);
  809. }
  810. }
  811. //
  812. // On Windows, we need to set the socket's blocking status again
  813. // after the asynchronous connect. Seems like a bug in .NET.
  814. //
  815. setBlock(fd, fd.Blocking);
  816. if(AssemblyUtil.platform_ == AssemblyUtil.Platform.NonWindows)
  817. {
  818. //
  819. // Prevent self connect (self connect happens on Linux when a client tries to connect to
  820. // a server which was just deactivated if the client socket re-uses the same ephemeral
  821. // port as the server).
  822. //
  823. EndPoint remoteAddr = getRemoteAddress(fd);
  824. if(remoteAddr != null && remoteAddr.Equals(getLocalAddress(fd)))
  825. {
  826. throw new Ice.ConnectionRefusedException();
  827. }
  828. }
  829. }
  830. #endif
  831. public static EndPoint getAddressForServer(string host, int port, int protocol, bool preferIPv6)
  832. {
  833. if(host.Length == 0)
  834. {
  835. if(protocol != EnableIPv4)
  836. {
  837. return new IPEndPoint(IPAddress.IPv6Any, port);
  838. }
  839. else
  840. {
  841. return new IPEndPoint(IPAddress.Any, port);
  842. }
  843. }
  844. return getAddresses(host, port, protocol, Ice.EndpointSelectionType.Ordered, preferIPv6, true)[0];
  845. }
  846. public static List<EndPoint> getAddresses(string host, int port, int protocol,
  847. Ice.EndpointSelectionType selType, bool preferIPv6, bool blocking)
  848. {
  849. List<EndPoint> addresses = new List<EndPoint>();
  850. if(host.Length == 0)
  851. {
  852. if(protocol != EnableIPv4)
  853. {
  854. addresses.Add(new IPEndPoint(IPAddress.IPv6Loopback, port));
  855. }
  856. if(protocol != EnableIPv6)
  857. {
  858. addresses.Add(new IPEndPoint(IPAddress.Loopback, port));
  859. }
  860. return addresses;
  861. }
  862. int retry = 5;
  863. repeatGetHostByName:
  864. try
  865. {
  866. //
  867. // No need for lookup if host is ip address.
  868. //
  869. try
  870. {
  871. IPAddress addr = IPAddress.Parse(host);
  872. if((addr.AddressFamily == AddressFamily.InterNetwork && protocol != EnableIPv6) ||
  873. (addr.AddressFamily == AddressFamily.InterNetworkV6 && protocol != EnableIPv4))
  874. {
  875. addresses.Add(new IPEndPoint(addr, port));
  876. return addresses;
  877. }
  878. else
  879. {
  880. Ice.DNSException e = new Ice.DNSException();
  881. e.host = host;
  882. throw e;
  883. }
  884. }
  885. catch(FormatException)
  886. {
  887. #if !SILVERLIGHT
  888. if(!blocking)
  889. {
  890. return addresses;
  891. }
  892. #endif
  893. }
  894. #if SILVERLIGHT
  895. addresses.Add(new DnsEndPoint(host, port));
  896. #else
  897. # if COMPACT
  898. foreach(IPAddress a in Dns.GetHostEntry(host).AddressList)
  899. # else
  900. foreach(IPAddress a in Dns.GetHostAddresses(host))
  901. # endif
  902. {
  903. if((a.AddressFamily == AddressFamily.InterNetwork && protocol != EnableIPv6) ||
  904. (a.AddressFamily == AddressFamily.InterNetworkV6 && protocol != EnableIPv4))
  905. {
  906. addresses.Add(new IPEndPoint(a, port));
  907. }
  908. }
  909. #endif
  910. if(selType == Ice.EndpointSelectionType.Random)
  911. {
  912. IceUtilInternal.Collections.Shuffle(ref addresses);
  913. }
  914. if(protocol == EnableBoth)
  915. {
  916. if(preferIPv6)
  917. {
  918. IceUtilInternal.Collections.Sort(ref addresses, _preferIPv6Comparator);
  919. }
  920. else
  921. {
  922. IceUtilInternal.Collections.Sort(ref addresses, _preferIPv4Comparator);
  923. }
  924. }
  925. }
  926. catch(SocketException ex)
  927. {
  928. if(socketErrorCode(ex) == SocketError.TryAgain && --retry >= 0)
  929. {
  930. goto repeatGetHostByName;
  931. }
  932. Ice.DNSException e = new Ice.DNSException(ex);
  933. e.host = host;
  934. throw e;
  935. }
  936. catch(System.Exception ex)
  937. {
  938. Ice.DNSException e = new Ice.DNSException(ex);
  939. e.host = host;
  940. throw e;
  941. }
  942. //
  943. // No InterNetwork/InterNetworkV6 available.
  944. //
  945. if(addresses.Count == 0)
  946. {
  947. Ice.DNSException e = new Ice.DNSException();
  948. e.host = host;
  949. throw e;
  950. }
  951. return addresses;
  952. }
  953. public static IPAddress[] getLocalAddresses(int protocol)
  954. {
  955. #if SILVERLIGHT
  956. return new List<IPAddress>().ToArray();
  957. #else
  958. List<IPAddress> addresses;
  959. int retry = 5;
  960. repeatGetHostByName:
  961. try
  962. {
  963. addresses = new List<IPAddress>();
  964. # if !COMPACT && !UNITY
  965. NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
  966. foreach(NetworkInterface ni in nics)
  967. {
  968. IPInterfaceProperties ipProps = ni.GetIPProperties();
  969. UnicastIPAddressInformationCollection uniColl = ipProps.UnicastAddresses;
  970. foreach(UnicastIPAddressInformation uni in uniColl)
  971. {
  972. if((uni.Address.AddressFamily == AddressFamily.InterNetwork && protocol != EnableIPv6) ||
  973. (uni.Address.AddressFamily == AddressFamily.InterNetworkV6 && protocol != EnableIPv4))
  974. {
  975. if(!IPAddress.IsLoopback(uni.Address))
  976. {
  977. addresses.Add(uni.Address);
  978. }
  979. }
  980. }
  981. }
  982. # else
  983. # if COMPACT
  984. foreach(IPAddress a in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
  985. # else
  986. foreach(IPAddress a in Dns.GetHostAddresses(Dns.GetHostName()))
  987. # endif
  988. {
  989. if((a.AddressFamily == AddressFamily.InterNetwork && protocol != EnableIPv6) ||
  990. (a.AddressFamily == AddressFamily.InterNetworkV6 && protocol != EnableIPv4))
  991. {
  992. if(!IPAddress.IsLoopback(a))
  993. {
  994. addresses.Add(a);
  995. }
  996. }
  997. }
  998. # endif
  999. }
  1000. catch(SocketException ex)
  1001. {
  1002. if(socketErrorCode(ex) == SocketError.TryAgain && --retry >= 0)
  1003. {
  1004. goto repeatGetHostByName;
  1005. }
  1006. Ice.DNSException e = new Ice.DNSException(ex);
  1007. e.host = "0.0.0.0";
  1008. throw e;
  1009. }
  1010. catch(System.Exception ex)
  1011. {
  1012. Ice.DNSException e = new Ice.DNSException(ex);
  1013. e.host = "0.0.0.0";
  1014. throw e;
  1015. }
  1016. return addresses.ToArray();
  1017. #endif
  1018. }
  1019. public static void
  1020. setTcpBufSize(Socket socket, Ice.Properties properties, Ice.Logger logger)
  1021. {
  1022. //
  1023. // By default, on Windows we use a 128KB buffer size. On Unix
  1024. // platforms, we use the system defaults.
  1025. //
  1026. int dfltBufSize = 0;
  1027. if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows)
  1028. {
  1029. dfltBufSize = 128 * 1024;
  1030. }
  1031. int sizeRequested = properties.getPropertyAsIntWithDefault("Ice.TCP.RcvSize", dfltBufSize);
  1032. if(sizeRequested > 0)
  1033. {
  1034. //
  1035. // Try to set the buffer size. The kernel will silently adjust
  1036. // the size to an acceptable value. Then read the size back to
  1037. // get the size that was actually set.
  1038. //
  1039. setRecvBufferSize(socket, sizeRequested);
  1040. int size = getRecvBufferSize(socket);
  1041. if(size < sizeRequested) // Warn if the size that was set is less than the requested size.
  1042. {
  1043. logger.warning("TCP receive buffer size: requested size of " + sizeRequested + " adjusted to " +
  1044. size);
  1045. }
  1046. }
  1047. sizeRequested = properties.getPropertyAsIntWithDefault("Ice.TCP.SndSize", dfltBufSize);
  1048. if(sizeRequested > 0)
  1049. {
  1050. //
  1051. // Try to set the buffer size. The kernel will silently adjust
  1052. // the size to an acceptable value. Then read the size back to
  1053. // get the size that was actually set.
  1054. //
  1055. setSendBufferSize(socket, sizeRequested);
  1056. int size = getSendBufferSize(socket);
  1057. if(size < sizeRequested) // Warn if the size that was set is less than the requested size.
  1058. {
  1059. logger.warning("TCP send buffer size: requested size of " + sizeRequested + " adjusted to " + size);
  1060. }
  1061. }
  1062. }
  1063. public static List<string> getHostsForEndpointExpand(string host, int protocol, bool includeLoopback)
  1064. {
  1065. bool wildcard = host.Length == 0;
  1066. if(!wildcard)
  1067. {
  1068. try
  1069. {
  1070. IPAddress addr = IPAddress.Parse(host);
  1071. wildcard = addr.Equals(IPAddress.Any) || addr.Equals(IPAddress.IPv6Any);
  1072. }
  1073. catch(Exception)
  1074. {
  1075. }
  1076. }
  1077. List<string> hosts = new List<string>();
  1078. if(wildcard)
  1079. {
  1080. IPAddress[] addrs = getLocalAddresses(protocol);
  1081. foreach(IPAddress a in addrs)
  1082. {
  1083. #if COMPACT
  1084. if(!IPAddress.IsLoopback(a))
  1085. #else
  1086. if(!a.IsIPv6LinkLocal)
  1087. #endif
  1088. {
  1089. hosts.Add(a.ToString());
  1090. }
  1091. }
  1092. if(includeLoopback || hosts.Count == 0)
  1093. {
  1094. if(protocol != EnableIPv6)
  1095. {
  1096. hosts.Add("127.0.0.1");
  1097. }
  1098. if(protocol != EnableIPv4)
  1099. {
  1100. hosts.Add("0:0:0:0:0:0:0:1");
  1101. }
  1102. }
  1103. }
  1104. return hosts;
  1105. }
  1106. public static string fdToString(Socket socket, NetworkProxy proxy, EndPoint target)
  1107. {
  1108. try
  1109. {
  1110. if(socket == null)
  1111. {
  1112. return "<closed>";
  1113. }
  1114. EndPoint remote = getRemoteAddress(socket);
  1115. System.Text.StringBuilder s = new System.Text.StringBuilder();
  1116. s.Append("local address = " + localAddrToString(getLocalAddress(socket)));
  1117. if(proxy != null)
  1118. {
  1119. if(remote == null)
  1120. {
  1121. remote = proxy.getAddress();
  1122. }
  1123. s.Append("\n" + proxy.getName() + " proxy address = " + remoteAddrToString(remote));
  1124. s.Append("\nremote address = " + remoteAddrToString(target));
  1125. }
  1126. else
  1127. {
  1128. if(remote == null)
  1129. {
  1130. remote = target;
  1131. }
  1132. s.Append("\nremote address = " + remoteAddrToString(remote));
  1133. }
  1134. return s.ToString();
  1135. }
  1136. catch(ObjectDisposedException)
  1137. {
  1138. return "<closed>";
  1139. }
  1140. }
  1141. public static string fdToString(Socket socket)
  1142. {
  1143. try
  1144. {
  1145. if(socket == null)
  1146. {
  1147. return "<closed>";
  1148. }
  1149. System.Text.StringBuilder s = new System.Text.StringBuilder();
  1150. s.Append("local address = " + localAddrToString(getLocalAddress(socket)));
  1151. s.Append("\nremote address = " + remoteAddrToString(getRemoteAddress(socket)));
  1152. return s.ToString();
  1153. }
  1154. catch(ObjectDisposedException)
  1155. {
  1156. return "<closed>";
  1157. }
  1158. }
  1159. public static string fdLocalAddressToString(Socket socket)
  1160. {
  1161. return "local address = " + localAddrToString(getLocalAddress(socket));
  1162. }
  1163. public static string
  1164. addrToString(EndPoint addr)
  1165. {
  1166. return endpointAddressToString(addr) + ":" + endpointPort(addr);
  1167. }
  1168. public static string
  1169. localAddrToString(EndPoint endpoint)
  1170. {
  1171. if(endpoint == null)
  1172. {
  1173. #if SILVERLIGHT
  1174. return "<not available>";
  1175. #else
  1176. return "<not bound>";
  1177. #endif
  1178. }
  1179. return endpointAddressToString(endpoint) + ":" + endpointPort(endpoint);
  1180. }
  1181. public static string
  1182. remoteAddrToString(EndPoint endpoint)
  1183. {
  1184. if(endpoint == null)
  1185. {
  1186. return "<not connected>";
  1187. }
  1188. return endpointAddressToString(endpoint) + ":" + endpointPort(endpoint);
  1189. }
  1190. public static EndPoint
  1191. getLocalAddress(Socket socket)
  1192. {
  1193. // Silverlight socket doesn't exposes a local endpoint
  1194. #if !SILVERLIGHT
  1195. try
  1196. {
  1197. return socket.LocalEndPoint;
  1198. }
  1199. catch(SocketException ex)
  1200. {
  1201. throw new Ice.SocketException(ex);
  1202. }
  1203. #else
  1204. return null;
  1205. #endif
  1206. }
  1207. public static EndPoint
  1208. getRemoteAddress(Socket socket)
  1209. {
  1210. try
  1211. {
  1212. return (EndPoint)socket.RemoteEndPoint;
  1213. }
  1214. catch(SocketException)
  1215. {
  1216. }
  1217. return null;
  1218. }
  1219. private static int
  1220. getInterfaceIndex(string name)
  1221. {
  1222. #if !COMPACT && !SILVERLIGHT && !UNITY
  1223. NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
  1224. foreach(NetworkInterface ni in nics)
  1225. {
  1226. if(ni.Name == name)
  1227. {
  1228. IPInterfaceProperties ipProps = ni.GetIPProperties();
  1229. try
  1230. {
  1231. IPv6InterfaceProperties ipv6Props = ipProps.GetIPv6Properties();
  1232. if(ipv6Props != null)
  1233. {
  1234. return ipv6Props.Index;
  1235. }
  1236. }
  1237. catch(System.NotImplementedException)
  1238. {
  1239. }
  1240. }
  1241. }
  1242. #endif
  1243. return 0;
  1244. }
  1245. private static IPAddress
  1246. getInterfaceAddress(string name)
  1247. {
  1248. #if !COMPACT && !SILVERLIGHT && !UNITY
  1249. NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
  1250. foreach(NetworkInterface ni in nics)
  1251. {
  1252. if(ni.Name == name)
  1253. {
  1254. IPInterfaceProperties ipProps = ni.GetIPProperties();
  1255. UnicastIPAddressInformationCollection uniColl = ipProps.UnicastAddresses;
  1256. foreach(UnicastIPAddressInformation uni in uniColl)
  1257. {
  1258. if(uni.Address.AddressFamily == AddressFamily.InterNetwork)
  1259. {
  1260. return uni.Address;
  1261. }
  1262. }
  1263. }
  1264. }
  1265. #endif
  1266. return IPAddress.Any;
  1267. }
  1268. public static string
  1269. endpointAddressToString(EndPoint endpoint)
  1270. {
  1271. if(endpoint != null)
  1272. {
  1273. #if SILVERLIGHT
  1274. if(endpoint is DnsEndPoint)
  1275. {
  1276. DnsEndPoint dnsEndpoint = (DnsEndPoint)endpoint;
  1277. return dnsEndpoint.Host;
  1278. }
  1279. #endif
  1280. if(endpoint is IPEndPoint)
  1281. {
  1282. IPEndPoint ipEndpoint = (IPEndPoint) endpoint;
  1283. return ipEndpoint.Address.ToString();
  1284. }
  1285. }
  1286. return "";
  1287. }
  1288. public static int
  1289. endpointPort(EndPoint endpoint)
  1290. {
  1291. if(endpoint != null)
  1292. {
  1293. #if SILVERLIGHT
  1294. if(endpoint is DnsEndPoint)
  1295. {
  1296. DnsEndPoint dnsEndpoint = (DnsEndPoint)endpoint;
  1297. return dnsEndpoint.Port;
  1298. }
  1299. #endif
  1300. if(endpoint is IPEndPoint)
  1301. {
  1302. IPEndPoint ipEndpoint = (IPEndPoint) endpoint;
  1303. return ipEndpoint.Port;
  1304. }
  1305. }
  1306. return -1;
  1307. }
  1308. private class EndPointComparator : IComparer<EndPoint>
  1309. {
  1310. public EndPointComparator(bool ipv6)
  1311. {
  1312. _ipv6 = ipv6;
  1313. }
  1314. public int Compare(EndPoint lhs, EndPoint rhs)
  1315. {
  1316. if(lhs.AddressFamily == AddressFamily.InterNetwork &&
  1317. rhs.AddressFamily == AddressFamily.InterNetworkV6)
  1318. {
  1319. return _ipv6 ? 1 : -1;
  1320. }
  1321. else if(lhs.AddressFamily == AddressFamily.InterNetworkV6 &&
  1322. rhs.AddressFamily == AddressFamily.InterNetwork)
  1323. {
  1324. return _ipv6 ? -1 : 1;
  1325. }
  1326. else
  1327. {
  1328. return 0;
  1329. }
  1330. }
  1331. private bool _ipv6;
  1332. }
  1333. private readonly static EndPointComparator _preferIPv4Comparator = new EndPointComparator(false);
  1334. private readonly static EndPointComparator _preferIPv6Comparator = new EndPointComparator(true);
  1335. }
  1336. }