Socket_2_1.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. // System.Net.Sockets.Socket.cs
  2. //
  3. // Authors:
  4. // Phillip Pearson ([email protected])
  5. // Dick Porter <[email protected]>
  6. // Gonzalo Paniagua Javier ([email protected])
  7. // Sridhar Kulkarni ([email protected])
  8. // Brian Nickel ([email protected])
  9. //
  10. // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
  11. // http://www.myelin.co.nz
  12. // (c) 2004-2006 Novell, Inc. (http://www.novell.com)
  13. //
  14. //
  15. // Permission is hereby granted, free of charge, to any person obtaining
  16. // a copy of this software and associated documentation files (the
  17. // "Software"), to deal in the Software without restriction, including
  18. // without limitation the rights to use, copy, modify, merge, publish,
  19. // distribute, sublicense, and/or sell copies of the Software, and to
  20. // permit persons to whom the Software is furnished to do so, subject to
  21. // the following conditions:
  22. //
  23. // The above copyright notice and this permission notice shall be
  24. // included in all copies or substantial portions of the Software.
  25. //
  26. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  27. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  28. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  29. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  30. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  31. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  32. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  33. //
  34. using System;
  35. using System.Net;
  36. using System.Collections;
  37. using System.Runtime.CompilerServices;
  38. using System.Runtime.InteropServices;
  39. using System.Threading;
  40. using System.Reflection;
  41. using System.IO;
  42. using System.Net.Configuration;
  43. using System.Security;
  44. using System.Text;
  45. #if NET_2_0
  46. using System.Collections.Generic;
  47. using System.Net.NetworkInformation;
  48. #if !NET_2_1
  49. using System.Timers;
  50. #endif
  51. #endif
  52. namespace System.Net.Sockets {
  53. public partial class Socket : IDisposable {
  54. /*
  55. * These two fields are looked up by name by the runtime, don't change
  56. * their name without also updating the runtime code.
  57. */
  58. private static int ipv4Supported = -1, ipv6Supported = -1;
  59. static Socket ()
  60. {
  61. // initialize ipv4Supported and ipv6Supported
  62. CheckProtocolSupport ();
  63. }
  64. internal static void CheckProtocolSupport ()
  65. {
  66. if(ipv4Supported == -1) {
  67. try {
  68. Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  69. tmp.Close();
  70. ipv4Supported = 1;
  71. } catch {
  72. ipv4Supported = 0;
  73. }
  74. }
  75. if (ipv6Supported == -1) {
  76. #if !NET_2_1
  77. #if NET_2_0 && CONFIGURATION_DEP
  78. SettingsSection config;
  79. config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection ("system.net/settings");
  80. if (config != null)
  81. ipv6Supported = config.Ipv6.Enabled ? -1 : 0;
  82. #else
  83. NetConfig config = System.Configuration.ConfigurationSettings.GetConfig("system.net/settings") as NetConfig;
  84. if (config != null)
  85. ipv6Supported = config.ipv6Enabled ? -1 : 0;
  86. #endif
  87. #endif
  88. if (ipv6Supported != 0) {
  89. try {
  90. Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
  91. tmp.Close();
  92. ipv6Supported = 1;
  93. } catch {
  94. ipv6Supported = 0;
  95. }
  96. }
  97. }
  98. }
  99. public static bool SupportsIPv4 {
  100. get {
  101. CheckProtocolSupport();
  102. return ipv4Supported == 1;
  103. }
  104. }
  105. #if NET_2_0
  106. [ObsoleteAttribute ("Use OSSupportsIPv6 instead")]
  107. #endif
  108. public static bool SupportsIPv6 {
  109. get {
  110. CheckProtocolSupport();
  111. return ipv6Supported == 1;
  112. }
  113. }
  114. #if NET_2_1
  115. public static bool OSSupportsIPv4 {
  116. get {
  117. CheckProtocolSupport();
  118. return ipv4Supported == 1;
  119. }
  120. }
  121. #endif
  122. #if NET_2_1
  123. public static bool OSSupportsIPv6 {
  124. get {
  125. CheckProtocolSupport();
  126. return ipv6Supported == 1;
  127. }
  128. }
  129. #elif NET_2_0
  130. public static bool OSSupportsIPv6 {
  131. get {
  132. NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces ();
  133. foreach (NetworkInterface adapter in nics) {
  134. if (adapter.Supports (NetworkInterfaceComponent.IPv6))
  135. return true;
  136. }
  137. return false;
  138. }
  139. }
  140. #endif
  141. /* the field "socket" is looked up by name by the runtime */
  142. private IntPtr socket;
  143. private AddressFamily address_family;
  144. private SocketType socket_type;
  145. private ProtocolType protocol_type;
  146. internal bool blocking=true;
  147. Thread blocking_thread;
  148. #if NET_2_0
  149. private bool isbound;
  150. #endif
  151. /* When true, the socket was connected at the time of
  152. * the last IO operation
  153. */
  154. private bool connected;
  155. /* true if we called Close_internal */
  156. private bool closed;
  157. internal bool disposed;
  158. /*
  159. * This EndPoint is used when creating new endpoints. Because
  160. * there are many types of EndPoints possible,
  161. * seed_endpoint.Create(addr) is used for creating new ones.
  162. * As such, this value is set on Bind, SentTo, ReceiveFrom,
  163. * Connect, etc.
  164. */
  165. internal EndPoint seed_endpoint = null;
  166. #if !TARGET_JVM
  167. // Creates a new system socket, returning the handle
  168. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  169. private extern IntPtr Socket_internal(AddressFamily family,
  170. SocketType type,
  171. ProtocolType proto,
  172. out int error);
  173. #endif
  174. public Socket(AddressFamily family, SocketType type, ProtocolType proto)
  175. {
  176. #if NET_2_1
  177. if (family == AddressFamily.Unspecified)
  178. throw new ArgumentException ("family");
  179. #endif
  180. address_family=family;
  181. socket_type=type;
  182. protocol_type=proto;
  183. int error;
  184. socket = Socket_internal (family, type, proto, out error);
  185. if (error != 0)
  186. throw new SocketException (error);
  187. #if !NET_2_1
  188. SocketDefaults ();
  189. #endif
  190. }
  191. ~Socket ()
  192. {
  193. Dispose (false);
  194. }
  195. public AddressFamily AddressFamily {
  196. get { return address_family; }
  197. }
  198. #if !TARGET_JVM
  199. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  200. private extern static void Blocking_internal(IntPtr socket,
  201. bool block,
  202. out int error);
  203. #endif
  204. public bool Blocking {
  205. get {
  206. return(blocking);
  207. }
  208. set {
  209. if (disposed && closed)
  210. throw new ObjectDisposedException (GetType ().ToString ());
  211. int error;
  212. Blocking_internal (socket, value, out error);
  213. if (error != 0)
  214. throw new SocketException (error);
  215. blocking=value;
  216. }
  217. }
  218. public bool Connected {
  219. get { return connected; }
  220. internal set { connected = value; }
  221. }
  222. public ProtocolType ProtocolType {
  223. get { return protocol_type; }
  224. }
  225. #if NET_2_0
  226. public bool NoDelay {
  227. get {
  228. if (disposed && closed)
  229. throw new ObjectDisposedException (GetType ().ToString ());
  230. ThrowIfUpd ();
  231. return (int)(GetSocketOption (
  232. SocketOptionLevel.Tcp,
  233. SocketOptionName.NoDelay)) != 0;
  234. }
  235. set {
  236. if (disposed && closed)
  237. throw new ObjectDisposedException (GetType ().ToString ());
  238. ThrowIfUpd ();
  239. SetSocketOption (
  240. SocketOptionLevel.Tcp,
  241. SocketOptionName.NoDelay, value ? 1 : 0);
  242. }
  243. }
  244. public int ReceiveBufferSize {
  245. get {
  246. if (disposed && closed) {
  247. throw new ObjectDisposedException (GetType ().ToString ());
  248. }
  249. return((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer));
  250. }
  251. set {
  252. if (disposed && closed) {
  253. throw new ObjectDisposedException (GetType ().ToString ());
  254. }
  255. if (value < 0) {
  256. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than zero");
  257. }
  258. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, value);
  259. }
  260. }
  261. public int SendBufferSize {
  262. get {
  263. if (disposed && closed) {
  264. throw new ObjectDisposedException (GetType ().ToString ());
  265. }
  266. return((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.SendBuffer));
  267. }
  268. set {
  269. if (disposed && closed) {
  270. throw new ObjectDisposedException (GetType ().ToString ());
  271. }
  272. if (value < 0) {
  273. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than zero");
  274. }
  275. SetSocketOption (SocketOptionLevel.Socket,
  276. SocketOptionName.SendBuffer,
  277. value);
  278. }
  279. }
  280. public short Ttl {
  281. get {
  282. if (disposed && closed) {
  283. throw new ObjectDisposedException (GetType ().ToString ());
  284. }
  285. short ttl_val;
  286. if (address_family == AddressFamily.InterNetwork) {
  287. ttl_val = (short)((int)GetSocketOption (SocketOptionLevel.IP, SocketOptionName.IpTimeToLive));
  288. } else if (address_family == AddressFamily.InterNetworkV6) {
  289. ttl_val = (short)((int)GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.HopLimit));
  290. } else {
  291. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  292. }
  293. return(ttl_val);
  294. }
  295. set {
  296. if (disposed && closed) {
  297. throw new ObjectDisposedException (GetType ().ToString ());
  298. }
  299. if (address_family == AddressFamily.InterNetwork) {
  300. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, value);
  301. } else if (address_family == AddressFamily.InterNetworkV6) {
  302. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.HopLimit, value);
  303. } else {
  304. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  305. }
  306. }
  307. }
  308. #endif
  309. // Returns the remote endpoint details in addr and port
  310. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  311. private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, out int error);
  312. public EndPoint RemoteEndPoint {
  313. get {
  314. if (disposed && closed)
  315. throw new ObjectDisposedException (GetType ().ToString ());
  316. /*
  317. * If the seed EndPoint is null, Connect, Bind,
  318. * etc has not yet been called. MS returns null
  319. * in this case.
  320. */
  321. if (seed_endpoint == null)
  322. return null;
  323. SocketAddress sa;
  324. int error;
  325. sa=RemoteEndPoint_internal(socket, out error);
  326. if (error != 0)
  327. throw new SocketException (error);
  328. return seed_endpoint.Create (sa);
  329. }
  330. }
  331. protected virtual void Dispose (bool explicitDisposing)
  332. {
  333. if (disposed)
  334. return;
  335. disposed = true;
  336. connected = false;
  337. if ((int) socket != -1) {
  338. int error;
  339. closed = true;
  340. IntPtr x = socket;
  341. socket = (IntPtr) (-1);
  342. Close_internal (x, out error);
  343. if (blocking_thread != null) {
  344. blocking_thread.Abort ();
  345. blocking_thread = null;
  346. }
  347. if (error != 0)
  348. throw new SocketException (error);
  349. }
  350. }
  351. #if NET_2_1
  352. public void Dispose ()
  353. #else
  354. void IDisposable.Dispose ()
  355. #endif
  356. {
  357. Dispose (true);
  358. GC.SuppressFinalize (this);
  359. }
  360. // Closes the socket
  361. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  362. private extern static void Close_internal(IntPtr socket, out int error);
  363. public void Close ()
  364. {
  365. ((IDisposable) this).Dispose ();
  366. }
  367. // Connects to the remote address
  368. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  369. private extern static void Connect_internal(IntPtr sock,
  370. SocketAddress sa,
  371. out int error);
  372. public void Connect (EndPoint remote_end)
  373. {
  374. SocketAddress serial = null;
  375. if (disposed && closed)
  376. throw new ObjectDisposedException (GetType ().ToString ());
  377. if (remote_end == null)
  378. throw new ArgumentNullException("remote_end");
  379. if (remote_end is IPEndPoint) {
  380. IPEndPoint ep = (IPEndPoint) remote_end;
  381. if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
  382. throw new SocketException ((int) SocketError.AddressNotAvailable);
  383. }
  384. #if NET_2_1
  385. if (protocol_type != ProtocolType.Tcp)
  386. throw new SocketException ((int) SocketError.AccessDenied);
  387. DnsEndPoint dep = (remote_end as DnsEndPoint);
  388. if (dep != null)
  389. serial = dep.AsIPEndPoint ().Serialize ();
  390. else
  391. serial = remote_end.Serialize ();
  392. #elif NET_2_0
  393. /* TODO: check this for the 1.1 profile too */
  394. if (islistening)
  395. throw new InvalidOperationException ();
  396. serial = remote_end.Serialize ();
  397. #else
  398. serial = remote_end.Serialize ();
  399. #endif
  400. int error = 0;
  401. blocking_thread = Thread.CurrentThread;
  402. try {
  403. Connect_internal (socket, serial, out error);
  404. } catch (ThreadAbortException) {
  405. if (disposed) {
  406. Thread.ResetAbort ();
  407. error = (int) SocketError.Interrupted;
  408. }
  409. } finally {
  410. blocking_thread = null;
  411. }
  412. if (error != 0)
  413. throw new SocketException (error);
  414. connected=true;
  415. #if NET_2_0
  416. isbound = true;
  417. #endif
  418. seed_endpoint = remote_end;
  419. }
  420. #if NET_2_0
  421. public bool ReceiveAsync (SocketAsyncEventArgs e)
  422. {
  423. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  424. //
  425. // LAME SPEC: the ArgumentException is never thrown, instead an NRE is
  426. // thrown when e.Buffer and e.BufferList are null (works fine when one is
  427. // set to a valid object)
  428. if (disposed && closed)
  429. throw new ObjectDisposedException (GetType ().ToString ());
  430. // We do not support recv into multiple buffers yet
  431. if (e.BufferList != null)
  432. throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
  433. e.DoOperation (SocketAsyncOperation.Receive, this);
  434. // We always return true for now
  435. return true;
  436. }
  437. public bool SendAsync (SocketAsyncEventArgs e)
  438. {
  439. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  440. if (disposed && closed)
  441. throw new ObjectDisposedException (GetType ().ToString ());
  442. if (e.Buffer == null && e.BufferList == null)
  443. throw new ArgumentException ("Either e.Buffer or e.BufferList must be valid buffers.");
  444. e.DoOperation (SocketAsyncOperation.Send, this);
  445. // We always return true for now
  446. return true;
  447. }
  448. #endif
  449. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  450. extern static bool Poll_internal (IntPtr socket, SelectMode mode, int timeout, out int error);
  451. /* This overload is needed as the async Connect method
  452. * also needs to check the socket error status, but
  453. * getsockopt(..., SO_ERROR) clears the error.
  454. */
  455. internal bool Poll (int time_us, SelectMode mode, out int socket_error)
  456. {
  457. if (disposed && closed)
  458. throw new ObjectDisposedException (GetType ().ToString ());
  459. if (mode != SelectMode.SelectRead &&
  460. mode != SelectMode.SelectWrite &&
  461. mode != SelectMode.SelectError)
  462. throw new NotSupportedException ("'mode' parameter is not valid.");
  463. int error;
  464. bool result = Poll_internal (socket, mode, time_us, out error);
  465. if (error != 0)
  466. throw new SocketException (error);
  467. socket_error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
  468. if (mode == SelectMode.SelectWrite && result) {
  469. /* Update the connected state; for
  470. * non-blocking Connect()s this is
  471. * when we can find out that the
  472. * connect succeeded.
  473. */
  474. if (socket_error == 0) {
  475. connected = true;
  476. }
  477. }
  478. return result;
  479. }
  480. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  481. private extern static int Receive_internal(IntPtr sock,
  482. byte[] buffer,
  483. int offset,
  484. int count,
  485. SocketFlags flags,
  486. out int error);
  487. internal int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
  488. {
  489. int nativeError;
  490. int ret = Receive_internal (socket, buf, offset, size, flags, out nativeError);
  491. error = (SocketError) nativeError;
  492. if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
  493. connected = false;
  494. else
  495. connected = true;
  496. return ret;
  497. }
  498. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  499. private extern static void GetSocketOption_obj_internal(IntPtr socket,
  500. SocketOptionLevel level, SocketOptionName name, out object obj_val,
  501. out int error);
  502. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  503. private extern static int Send_internal(IntPtr sock,
  504. byte[] buf, int offset,
  505. int count,
  506. SocketFlags flags,
  507. out int error);
  508. internal int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
  509. {
  510. if (size == 0) {
  511. error = SocketError.Success;
  512. return 0;
  513. }
  514. int nativeError;
  515. int ret = Send_internal (socket, buf, offset, size, flags, out nativeError);
  516. error = (SocketError)nativeError;
  517. if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
  518. connected = false;
  519. else
  520. connected = true;
  521. return ret;
  522. }
  523. public object GetSocketOption (SocketOptionLevel level, SocketOptionName name)
  524. {
  525. if (disposed && closed)
  526. throw new ObjectDisposedException (GetType ().ToString ());
  527. object obj_val;
  528. int error;
  529. GetSocketOption_obj_internal(socket, level, name, out obj_val,
  530. out error);
  531. if (error != 0)
  532. throw new SocketException (error);
  533. if (name == SocketOptionName.Linger) {
  534. return((LingerOption)obj_val);
  535. } else if (name==SocketOptionName.AddMembership ||
  536. name==SocketOptionName.DropMembership) {
  537. return((MulticastOption)obj_val);
  538. } else if (obj_val is int) {
  539. return((int)obj_val);
  540. } else {
  541. return(obj_val);
  542. }
  543. }
  544. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  545. private extern static void Shutdown_internal (IntPtr socket, SocketShutdown how, out int error);
  546. public void Shutdown (SocketShutdown how)
  547. {
  548. if (disposed && closed)
  549. throw new ObjectDisposedException (GetType ().ToString ());
  550. int error;
  551. Shutdown_internal (socket, how, out error);
  552. if (error != 0)
  553. throw new SocketException (error);
  554. }
  555. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  556. private extern static void SetSocketOption_internal (IntPtr socket, SocketOptionLevel level,
  557. SocketOptionName name, object obj_val,
  558. byte [] byte_val, int int_val,
  559. out int error);
  560. public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, int opt_value)
  561. {
  562. if (disposed && closed)
  563. throw new ObjectDisposedException (GetType ().ToString ());
  564. int error;
  565. SetSocketOption_internal(socket, level, name, null,
  566. null, opt_value, out error);
  567. if (error != 0)
  568. throw new SocketException (error);
  569. }
  570. private void ThrowIfUpd ()
  571. {
  572. #if !NET_2_1
  573. if (protocol_type == ProtocolType.Udp)
  574. throw new SocketException ((int)SocketError.ProtocolOption);
  575. #endif
  576. }
  577. #if NET_2_1
  578. static MethodInfo check_socket_policy;
  579. static void CheckConnect (SocketAsyncEventArgs e, bool checkPolicy)
  580. {
  581. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  582. if (e.RemoteEndPoint == null)
  583. throw new ArgumentNullException ("remoteEP");
  584. if (e.BufferList != null)
  585. throw new ArgumentException ("Multiple buffers cannot be used with this method.");
  586. if (!checkPolicy)
  587. return;
  588. e.SocketError = SocketError.AccessDenied;
  589. if (check_socket_policy == null) {
  590. Type type = Type.GetType ("System.Windows.Browser.Net.CrossDomainPolicyManager, System.Windows.Browser, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e");
  591. check_socket_policy = type.GetMethod ("CheckEndPoint");
  592. if (check_socket_policy == null)
  593. throw new SecurityException ();
  594. }
  595. if ((bool) check_socket_policy.Invoke (null, new object [1] { e.RemoteEndPoint }))
  596. e.SocketError = SocketError.Success;
  597. }
  598. // only _directly_ used (with false) to download the socket policy
  599. internal bool ConnectAsync (SocketAsyncEventArgs e, bool checkPolicy)
  600. {
  601. if (disposed && closed)
  602. throw new ObjectDisposedException (GetType ().ToString ());
  603. CheckConnect (e, checkPolicy);
  604. e.DoOperation (SocketAsyncOperation.Connect, this);
  605. // We always return true for now
  606. return true;
  607. }
  608. public bool ConnectAsync (SocketAsyncEventArgs e)
  609. {
  610. return ConnectAsync (e, true);
  611. }
  612. public static bool ConnectAsync (SocketType socketType, ProtocolType protocolType, SocketAsyncEventArgs e)
  613. {
  614. CheckConnect (e, true);
  615. Socket s = new Socket (AddressFamily.InterNetwork, socketType, protocolType);
  616. e.DoOperation (SocketAsyncOperation.Connect, s);
  617. // We always return true for now
  618. return true;
  619. }
  620. public static void CancelConnectAsync (SocketAsyncEventArgs e)
  621. {
  622. if (e == null)
  623. throw new ArgumentNullException ("e");
  624. Socket s = e.ConnectSocket;
  625. if ((s != null) && (s.blocking_thread != null))
  626. s.blocking_thread.Abort ();
  627. }
  628. #endif
  629. }
  630. }