2009-05-14 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Fri, 15 May 2009 00:31:55 +0000 (00:31 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Fri, 15 May 2009 00:31:55 +0000 (00:31 -0000)
* Socket_2_1.cs: Add ConnectAsync support for NET_2_1 which will
ensure the EndPoint has a valid policy before connecting.
* SocketAsyncEventArgs.cs: Add support for IList<ArraySegment<byte>>
when sending. Add ConnectSocket for NET_2_1

svn path=/trunk/mcs/; revision=134171

mcs/class/System/System.Net.Sockets/ChangeLog
mcs/class/System/System.Net.Sockets/SocketAsyncEventArgs.cs
mcs/class/System/System.Net.Sockets/Socket_2_1.cs

index b6a63c32d9879c4be9e89e564be2d2c0b43d3408..88fcdde19c2f2a66b640d9367797503738e86b08 100644 (file)
@@ -1,3 +1,10 @@
+2009-05-14  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * Socket_2_1.cs: Add ConnectAsync support for NET_2_1 which will
+       ensure the EndPoint has a valid policy before connecting.
+       * SocketAsyncEventArgs.cs: Add support for IList<ArraySegment<byte>>
+       when sending. Add ConnectSocket for NET_2_1
+
 2009-05-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
 
        * TcpClient.cs:
index 722487e33f951752d406f222fdb1b8bdd6645680..f05cb2208dac22eaf124abbfb7443758adede138 100644 (file)
@@ -42,6 +42,7 @@ namespace System.Net.Sockets
                public Socket AcceptSocket { get; set; }
                public byte[] Buffer { get; private set; }
 
+               [MonoTODO ("not supported in all cases")]
                public IList<ArraySegment<byte>> BufferList {
                        get { return _bufferList; }
                        set {
@@ -66,6 +67,18 @@ namespace System.Net.Sockets
                public object UserToken { get; set; }
 
                Socket curSocket;
+#if NET_2_1
+               public Socket ConnectSocket {
+                       get {
+                               switch (SocketError) {
+                               case SocketError.AccessDenied:
+                                       return null;
+                               default:
+                                       return curSocket;
+                               }
+                       }
+               }
+#endif
                
                public SocketAsyncEventArgs ()
                {
@@ -152,6 +165,7 @@ namespace System.Net.Sockets
                        SocketError error = SocketError.Success;
                        
                        try {
+                               // FIXME: this does not support using BufferList
                                BytesTransferred = curSocket.Receive_nochecks (Buffer, Offset, Count, SocketFlags, out error);
                        } finally {
                                SocketError = error;
@@ -194,7 +208,17 @@ namespace System.Net.Sockets
                        SocketError error = SocketError.Success;
 
                        try {
-                               BytesTransferred = curSocket.Send_nochecks (Buffer, Offset, Count, SocketFlags.None, out error);
+                               if (Buffer != null) {
+                                       BytesTransferred = curSocket.Send_nochecks (Buffer, Offset, Count, SocketFlags.None, out error);
+                               } else if (BufferList != null) {
+                                       BytesTransferred = 0;
+                                       foreach (ArraySegment<byte> asb in BufferList) {
+                                               BytesTransferred += curSocket.Send_nochecks (asb.Array, asb.Offset, asb.Count, 
+                                                       SocketFlags.None, out error);
+                                               if (error != SocketError.Success)
+                                                       break;
+                                       }
+                               }
                        } finally {
                                SocketError = error;
                                OnCompleted (this);
index 5da64ba1c01f703319fe9473769e2e6c8a4d0bd1..df03ea10dd1512f39291545cc102817d32fd3438 100644 (file)
@@ -42,6 +42,7 @@ using System.Threading;
 using System.Reflection;
 using System.IO;
 using System.Net.Configuration;
+using System.Security;
 using System.Text;
 
 #if NET_2_0
@@ -387,12 +388,10 @@ namespace System.Net.Sockets {
                                IntPtr x = socket;
                                socket = (IntPtr) (-1);
                                Close_internal (x, out error);
-#if !NET_2_1
                                if (blocking_thread != null) {
                                        blocking_thread.Abort ();
                                        blocking_thread = null;
                                }
-#endif
                                if (error != 0)
                                        throw new SocketException (error);
                        }
@@ -425,6 +424,8 @@ namespace System.Net.Sockets {
 
                public void Connect (EndPoint remote_end)
                {
+                       SocketAddress serial = null;
+
                        if (disposed && closed)
                                throw new ObjectDisposedException (GetType ().ToString ());
 
@@ -436,28 +437,25 @@ namespace System.Net.Sockets {
                                if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
                                        throw new SocketException ((int) SocketError.AddressNotAvailable);
                        }
-
 #if NET_2_1
-                       // Check for SL2.0b1 restrictions
-                       // - tcp only
-                       // - SiteOfOrigin
-                       // - port 4502->4532 + default
                        if (protocol_type != ProtocolType.Tcp)
                                throw new SocketException ((int) SocketError.AccessDenied);
-                       //FIXME: replace 80 by Application.Curent.Host.Source.Port
-                       if (remote_end is IPEndPoint)
-                               if (((remote_end as IPEndPoint).Port < 4502 || (remote_end as IPEndPoint).Port > 4530) && (remote_end as IPEndPoint).Port != 80)
-                                       throw new SocketException ((int) SocketError.AccessDenied);
-                       else //unsuported endpoint type
-                               throw new SocketException ((int) SocketError.AccessDenied);
-                       //FIXME: check for Application.Curent.Host.Source.DnsSafeHost
+
+                       DnsEndPoint dep = (remote_end as DnsEndPoint);
+                       if (dep != null)
+                               serial = dep.AsIPEndPoint ().Serialize ();
+                       else
+                               serial = remote_end.Serialize ();
 #elif NET_2_0
                        /* TODO: check this for the 1.1 profile too */
                        if (islistening)
                                throw new InvalidOperationException ();
+
+                       serial = remote_end.Serialize ();
+#else
+                       serial = remote_end.Serialize ();
 #endif
 
-                       SocketAddress serial = remote_end.Serialize ();
                        int error = 0;
 
                        blocking_thread = Thread.CurrentThread;
@@ -465,9 +463,7 @@ namespace System.Net.Sockets {
                                Connect_internal (socket, serial, out error);
                        } catch (ThreadAbortException) {
                                if (disposed) {
-#if !NET_2_1 //2.1 profile does not contains Thread.ResetAbort
                                        Thread.ResetAbort ();
-#endif
                                        error = (int) SocketError.Interrupted;
                                }
                        } finally {
@@ -683,6 +679,72 @@ namespace System.Net.Sockets {
                                throw new SocketException ((int)SocketError.ProtocolOption);
 #endif
                }
+
+#if NET_2_1
+               static MethodInfo check_socket_policy;
+
+               static void CheckConnect (SocketAsyncEventArgs e, bool checkPolicy)
+               {
+                       // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
+
+                       if (e.RemoteEndPoint == null)
+                               throw new ArgumentNullException ("remoteEP");
+                       if (e.BufferList != null)
+                               throw new ArgumentException ("Multiple buffers cannot be used with this method.");
+
+                       if (!checkPolicy)
+                               return;
+
+                       if (check_socket_policy == null) {
+                               Type type = Type.GetType ("System.Windows.Browser.Net.CrossDomainPolicyManager, System.Windows.Browser, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e");
+                               check_socket_policy = type.GetMethod ("CheckEndPoint");
+                               if (check_socket_policy == null)
+                                       throw new SecurityException ();
+                       }
+                       if (!(bool) check_socket_policy.Invoke (null, new object [1] { e.RemoteEndPoint }))
+                               throw new SecurityException ();
+               }
+
+               // only _directly_ used (with false) to download the socket policy
+               internal bool ConnectAsync (SocketAsyncEventArgs e, bool checkPolicy)
+               {
+                       if (disposed && closed)
+                               throw new ObjectDisposedException (GetType ().ToString ());
+
+                       CheckConnect (e, checkPolicy);
+
+                       e.DoOperation (SocketAsyncOperation.Connect, this);
+
+                       // We always return true for now
+                       return true;
+               }
+
+               public bool ConnectAsync (SocketAsyncEventArgs e)
+               {
+                       return ConnectAsync (e, true);
+               }
+
+               public static bool ConnectAsync (SocketType socketType, ProtocolType protocolType, SocketAsyncEventArgs e)
+               {
+                       CheckConnect (e, true);
+
+                       Socket s = new Socket (AddressFamily.InterNetwork, socketType, protocolType);
+                       e.DoOperation (SocketAsyncOperation.Connect, s);
+
+                       // We always return true for now
+                       return true;
+               }
+
+               public static void CancelConnectAsync (SocketAsyncEventArgs e)
+               {
+                       if (e == null)
+                               throw new ArgumentNullException ("e");
+
+                       Socket s = e.ConnectSocket;
+                       if ((s != null) && (s.blocking_thread != null))
+                               s.blocking_thread.Abort ();
+               }
+#endif
        }
 }