[System.Net] Add support for .pac proxy config scripts on mac
[mono.git] / mcs / class / System / System.Net.Sockets / Socket.jvm.cs
1 // System.Net.Sockets.Socket.cs
2 //
3 // Authors:
4 //    Phillip Pearson (pp@myelin.co.nz)
5 //    Dick Porter <dick@ximian.com>
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
9 //    http://www.myelin.co.nz
10 // (c) 2004 Novell, Inc. (http://www.novell.com)
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.Net.Configuration;
37 using System.Runtime.InteropServices;
38 using System.Threading;
39
40 namespace System.Net.Sockets 
41 {
42         public class Socket : IDisposable 
43         {
44                 enum SocketOperation 
45                 {
46                         Accept,
47                         Connect,
48                         Receive,
49                         ReceiveFrom,
50                         Send,
51                         SendTo
52                 }
53
54                 [StructLayout (LayoutKind.Sequential)]
55                 private sealed class SocketAsyncResult: IAsyncResult 
56                 {
57                         /* Same structure in the runtime */
58                         public Socket Sock;
59 #if !TARGET_JVM
60                         public IntPtr handle;
61 #else
62                         public GHSocket handle;
63 #endif
64                         object state;
65                         AsyncCallback callback;
66                         WaitHandle waithandle;
67
68                         Exception delayedException;
69
70                         public EndPoint EndPoint;       // Connect,ReceiveFrom,SendTo
71                         public byte [] Buffer;          // Receive,ReceiveFrom,Send,SendTo
72                         public int Offset;              // Receive,ReceiveFrom,Send,SendTo
73                         public int Size;                // Receive,ReceiveFrom,Send,SendTo
74                         public SocketFlags SockFlags;   // Receive,ReceiveFrom,Send,SendTo
75
76                         // Return values
77                         Socket acc_socket;
78                         int total;
79
80                         bool completed_sync;
81                         bool completed;
82                         public bool blocking;
83                         internal int error;
84                         SocketOperation operation;
85                         public object ares;
86
87                         public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
88                         {
89                                 this.Sock = sock;
90                                 this.blocking = sock.blocking;
91                                 this.handle = sock.socket;
92                                 this.state = state;
93                                 this.callback = callback;
94                                 this.operation = operation;
95                                 SockFlags = SocketFlags.None;
96                         }
97
98                         public void CheckIfThrowDelayedException ()
99                         {
100                                 if (delayedException != null)
101                                         throw delayedException;
102
103                                 if (error != 0)
104                                         throw new SocketException (error);
105                         }
106
107                         void CompleteAllOnDispose (Queue queue)
108                         {
109                                 object [] pending = queue.ToArray ();
110                                 queue.Clear ();
111
112                                 WaitCallback cb;
113                                 for (int i = 0; i < pending.Length; i++) 
114                                 {
115                                         SocketAsyncResult ares = (SocketAsyncResult) pending [i];
116                                         cb = new WaitCallback (ares.CompleteDisposed);
117                                         ThreadPool.QueueUserWorkItem (cb, null);
118                                 }
119                         }
120
121                         void CompleteDisposed (object unused)
122                         {
123                                 Complete ();
124                         }
125
126                         public void Complete ()
127                         {
128                                 if (operation != SocketOperation.Receive && Sock.disposed)
129                                         delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
130
131                                 IsCompleted = true;
132
133                                 Queue queue = null;
134                                 if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) 
135                                 {
136                                         queue = Sock.readQ;
137                                 } 
138                                 else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) 
139                                 {
140                                         queue = Sock.writeQ;
141                                 }
142
143                                 if (queue != null) 
144                                 {
145                                         SocketAsyncCall sac = null;
146                                         SocketAsyncResult req = null;
147                                         lock (queue) 
148                                         {
149                                                 queue.Dequeue (); // remove ourselves
150                                                 if (queue.Count > 0) 
151                                                 {
152                                                         req = (SocketAsyncResult) queue.Peek ();
153                                                         if (!Sock.disposed) 
154                                                         {
155                                                                 Worker worker = new Worker (req);
156                                                                 sac = GetDelegate (worker, req.operation);
157                                                         } 
158                                                         else 
159                                                         {
160                                                                 CompleteAllOnDispose (queue);
161                                                         }
162                                                 }
163                                         }
164
165                                         if (sac != null)
166                                                 sac.BeginInvoke (null, req);
167                                 }
168
169                                 if (callback != null)
170                                         callback (this);
171                         }
172
173                         SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
174                         {
175                                 switch (op) 
176                                 {
177                                         case SocketOperation.Receive:
178                                                 return new SocketAsyncCall (worker.Receive);
179                                         case SocketOperation.ReceiveFrom:
180                                                 return new SocketAsyncCall (worker.ReceiveFrom);
181                                         case SocketOperation.Send:
182                                                 return new SocketAsyncCall (worker.Send);
183                                         case SocketOperation.SendTo:
184                                                 return new SocketAsyncCall (worker.SendTo);
185                                         default:
186                                                 return null; // never happens
187                                 }
188                         }
189
190                         public void Complete (bool synch)
191                         {
192                                 completed_sync = synch;
193                                 Complete ();
194                         }
195
196                         public void Complete (int total)
197                         {
198                                 this.total = total;
199                                 Complete ();
200                         }
201                         
202                         public void Complete (Exception e, bool synch)
203                         {
204                                 completed_sync = synch;
205                                 delayedException = e;
206                                 Complete ();
207                         }
208
209                         public void Complete (Exception e)
210                         {
211                                 delayedException = e;
212                                 Complete ();
213                         }
214
215                         public void Complete (Socket s)
216                         {
217                                 acc_socket = s;
218                                 Complete ();
219                         }
220
221                         public object AsyncState 
222                         {
223                                 get 
224                                 {
225                                         return state;
226                                 }
227                         }
228
229                         public WaitHandle AsyncWaitHandle 
230                         {
231                                 get 
232                                 {
233                                         lock (this) 
234                                         {
235                                                 if (waithandle == null)
236                                                         waithandle = new ManualResetEvent (completed);
237                                         }
238
239                                         return waithandle;
240                                 }
241                                 set 
242                                 {
243                                         waithandle=value;
244                                 }
245                         }
246
247                         public bool CompletedSynchronously 
248                         {
249                                 get 
250                                 {
251                                         return(completed_sync);
252                                 }
253                         }
254
255                         public bool IsCompleted 
256                         {
257                                 get 
258                                 {
259                                         return(completed);
260                                 }
261                                 set 
262                                 {
263                                         completed=value;
264                                         lock (this) 
265                                         {
266                                                 if (waithandle != null && value) 
267                                                 {
268                                                         ((ManualResetEvent) waithandle).Set ();
269                                                 }
270                                         }
271                                 }
272                         }
273                         
274                         public Socket Socket 
275                         {
276                                 get 
277                                 {
278                                         return acc_socket;
279                                 }
280                         }
281
282                         public int Total 
283                         {
284                                 get 
285                                 {
286                                         return total;
287                                 }
288                                 set 
289                                 { 
290                                         total = value; 
291                                 }
292                         }
293                 }
294
295                 private sealed class Worker 
296                 {
297                         SocketAsyncResult result;
298
299                         public Worker (SocketAsyncResult ares)
300                         {
301                                 this.result = ares;
302                         }
303                         
304                         public void Accept ()
305                         {
306                                 Socket acc_socket = null;
307                                 try 
308                                 {
309                                         acc_socket = result.Sock.Accept ();
310                                 } 
311                                 catch (Exception e) 
312                                 {
313                                         result.Complete (e);
314                                         return;
315                                 }
316
317                                 result.Complete (acc_socket);
318                         }
319
320                         public void Connect ()
321                         {
322                                 try 
323                                 {
324                                         result.Sock.Connect (result.EndPoint);
325                                         result.Sock.connected = true;
326                                 } 
327                                 catch (Exception e) 
328                                 {
329                                         result.Complete (e);
330                                         return;
331                                 }
332
333                                 result.Complete ();
334                         }
335
336 #if !TARGET_JVM
337                         public void Receive ()
338                         {
339                                 // Actual recv() done in the runtime
340                                 result.Complete ();
341                         }
342 #else
343                         public void Receive ()
344                         {
345                                 int total = 0;
346                                 try 
347                                 {
348                                         total = result.Sock.Receive_nochecks (result.Buffer,
349                                                 result.Offset,
350                                                 result.Size,
351                                                 result.SockFlags);
352                                 } 
353                                 catch (Exception e) 
354                                 {
355                                         result.Complete (e);
356                                         return;
357                                 }
358
359                                 result.Complete (total);
360                         }
361 #endif
362
363                         public void ReceiveFrom ()
364                         {
365                                 int total = 0;
366                                 try 
367                                 {
368                                         total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
369                                                 result.Offset,
370                                                 result.Size,
371                                                 result.SockFlags,
372                                                 ref result.EndPoint);
373                                 } 
374                                 catch (Exception e) 
375                                 {
376                                         result.Complete (e);
377                                         return;
378                                 }
379
380                                 result.Complete (total);
381                         }
382
383                         int send_so_far;
384
385                         void UpdateSendValues (int last_sent)
386                         {
387                                 if (result.error == 0) 
388                                 {
389                                         send_so_far += last_sent;
390                                         result.Offset += last_sent;
391                                         result.Size -= last_sent;
392                                 }
393                         }
394
395 #if !TARGET_JVM
396                         public void Send ()
397                         {
398                                 // Actual send() done in the runtime
399                                 if (result.error == 0) 
400                                 {
401                                         UpdateSendValues (result.Total);
402                                         if (result.Sock.disposed) 
403                                         {
404                                                 result.Complete ();
405                                                 return;
406                                         }
407
408                                         if (result.Size > 0) 
409                                         {
410                                                 SocketAsyncCall sac = new SocketAsyncCall (this.Send);
411                                                 sac.BeginInvoke (null, result);
412                                                 return; // Have to finish writing everything. See bug #74475.
413                                         }
414                                         result.Total = send_so_far;
415                                 }
416                                 result.Complete ();
417                         }
418 #else
419                         public void Send ()
420                         {
421                                 int total = 0;
422                                 try 
423                                 {
424                                         total = result.Sock.Send_nochecks (result.Buffer,
425                                                 result.Offset,
426                                                 result.Size,
427                                                 result.SockFlags);
428
429                                         UpdateSendValues (total);
430                                         if (result.Size > 0) 
431                                         {
432                                                 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
433                                                 sac.BeginInvoke (null, result);
434                                                 return; // Have to finish writing everything. See bug #74475.
435                                         }
436                                         result.Total = send_so_far;
437                                 } 
438                                 catch (Exception e) 
439                                 {
440                                         result.Complete (e);
441                                         return;
442                                 }
443
444                                 result.Complete ();
445                         }
446 #endif
447
448                         public void SendTo ()
449                         {
450                                 int total = 0;
451                                 try 
452                                 {
453                                         total = result.Sock.SendTo_nochecks (result.Buffer,
454                                                 result.Offset,
455                                                 result.Size,
456                                                 result.SockFlags,
457                                                 result.EndPoint);
458
459                                         UpdateSendValues (total);
460                                         if (result.Size > 0) 
461                                         {
462                                                 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
463                                                 sac.BeginInvoke (null, result);
464                                                 return; // Have to finish writing everything. See bug #74475.
465                                         }
466                                         result.Total = send_so_far;
467                                 } 
468                                 catch (Exception e) 
469                                 {
470                                         result.Complete (e);
471                                         return;
472                                 }
473
474                                 result.Complete ();
475                         }
476                 }
477
478                         
479                 /* the field "socket" is looked up by name by the runtime */
480 #if !TARGET_JVM
481                 private IntPtr socket;
482 #else
483                 private GHSocket socket;
484 #endif
485                 private AddressFamily address_family;
486                 private SocketType socket_type;
487                 private ProtocolType protocol_type;
488                 internal bool blocking=true;
489                 private Queue readQ = new Queue (2);
490                 private Queue writeQ = new Queue (2);
491                 
492
493                 delegate void SocketAsyncCall ();
494                 /*
495                  *      These two fields are looked up by name by the runtime, don't change
496                  *  their name without also updating the runtime code.
497                  */
498                 private static int ipv4Supported = -1, ipv6Supported = -1;
499
500                 /* When true, the socket was connected at the time of
501                  * the last IO operation
502                  */
503                 private bool connected=false;
504                 /* true if we called Close_internal */
505                 private bool closed;
506                 internal bool disposed;
507
508                 /* Used in LocalEndPoint and RemoteEndPoint if the
509                  * Mono.Posix assembly is available
510                  */
511                 private static object unixendpoint=null;
512                 private static Type unixendpointtype=null;
513                 
514                 static void AddSockets (ArrayList sockets, IList list, string name)
515                 {
516                         if (list != null) 
517                         {
518                                 foreach (Socket sock in list) 
519                                 {
520                                         if (sock == null) // MS throws a NullRef
521                                                 throw new ArgumentNullException (name, "Contains a null element");
522                                         sockets.Add (sock);
523                                 }
524                         }
525
526                         sockets.Add (null);
527                 }
528
529 #if !TARGET_JVM
530                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
531                 private extern static void Select_internal (ref Socket [] sockets,
532                                                         int microSeconds,
533                                                         out int error);
534 #else
535                 private static void Select_internal (ref Socket [] sockets, int microSeconds, out int error)
536                 {
537                         GHSocketFactory.Select_internal(ref sockets, microSeconds, out error);
538                 }
539 #endif
540
541                 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
542                 {
543                         ArrayList list = new ArrayList ();
544                         AddSockets (list, checkRead, "checkRead");
545                         AddSockets (list, checkWrite, "checkWrite");
546                         AddSockets (list, checkError, "checkError");
547
548                         if (list.Count == 3) 
549                         {
550                                 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
551                                         "All the lists are null or empty.");
552                         }
553
554                         int error;
555                         /*
556                          * The 'sockets' array contains: READ socket 0-n, null,
557                          *                               WRITE socket 0-n, null,
558                          *                               ERROR socket 0-n, null
559                          */
560                         Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
561                         Select_internal (ref sockets, microSeconds, out error);
562
563                         if (error != 0)
564                                 throw new SocketException (error);
565
566                         if (checkRead != null)
567                                 checkRead.Clear ();
568
569                         if (checkWrite != null)
570                                 checkWrite.Clear ();
571
572                         if (checkError != null)
573                                 checkError.Clear ();
574
575                         if (sockets == null)
576                                 return;
577
578                         int mode = 0;
579                         int count = sockets.Length;
580                         IList currentList = checkRead;
581                         for (int i = 0; i < count; i++) 
582                         {
583                                 Socket sock = sockets [i];
584                                 if (sock == null) 
585                                 { // separator
586                                         currentList = (mode == 0) ? checkWrite : checkError;
587                                         mode++;
588                                         continue;
589                                 }
590
591                                 if (currentList != null) 
592                                 {
593                                         sock.connected = true;
594                                         currentList.Add (sock);
595                                 }
596                         }
597                 }
598
599 #if !TARGET_JVM
600                 static Socket() 
601                 {
602                         Assembly ass;
603                         
604                         try {
605                                 ass = Assembly.Load (Consts.AssemblyMono_Posix);
606                         } catch (FileNotFoundException) {
607                                 return;
608                         }
609                                 
610                         unixendpointtype=ass.GetType("Mono.Posix.UnixEndPoint");
611
612                         /* The endpoint Create() method is an instance
613                          * method :-(
614                          */
615                         Type[] arg_types=new Type[1];
616                         arg_types[0]=typeof(string);
617                         ConstructorInfo cons=unixendpointtype.GetConstructor(arg_types);
618
619                         object[] args=new object[1];
620                         args[0]="";
621
622                         unixendpoint=cons.Invoke(args);
623                 }
624 #endif
625
626 #if !TARGET_JVM
627                 // private constructor used by Accept, which already
628                 // has a socket handle to use
629                 private Socket(AddressFamily family, SocketType type,
630                         ProtocolType proto, IntPtr sock) 
631 #else
632                 // private constructor used by Accept, which already
633                 // has a socket handle to use
634                 private Socket(AddressFamily family, SocketType type,
635                         ProtocolType proto, GHSocket sock) 
636                 {
637 #endif
638                         address_family=family;
639                         socket_type=type;
640                         protocol_type=proto;
641                         
642                         socket=sock;
643                         connected=true;
644                 }
645
646
647 #if !TARGET_JVM
648                 // Creates a new system socket, returning the handle
649                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
650                 private extern IntPtr Socket_internal(AddressFamily family,
651                         SocketType type,
652                         ProtocolType proto,
653                         out int error);
654 #else
655                 private GHSocket Socket_internal(AddressFamily family,
656                         SocketType type,
657                         ProtocolType proto,
658                         out int error)
659                 {
660                         return GHSocketFactory.Socket_internal(family, type, proto, out error);
661                 }
662 #endif  
663
664                 public Socket(AddressFamily family, SocketType type,
665                         ProtocolType proto) 
666                 {
667                         address_family=family;
668                         socket_type=type;
669                         protocol_type=proto;
670                         int error;
671                         
672                         socket=Socket_internal(family, type, proto, out error);
673                         if (error != 0) {
674                                 throw new SocketException (error);
675                         }
676                 }
677
678                 public AddressFamily AddressFamily 
679                 {
680                         get 
681                         {
682                                 return(address_family);
683                         }
684                 }
685
686 #if !TARGET_JVM
687                 // Returns the amount of data waiting to be read on socket
688                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
689                 private extern static int Available_internal(IntPtr socket,
690                         out int error);
691 #else
692                 private int Available_internal(GHSocket socket, out int error)
693                 {
694                         return socket.Available_internal(out error);
695                 }
696 #endif
697
698                 public int Available 
699                 {
700                         get 
701                         {
702                                 EnsureStillUsable();
703
704                                 int ret, error;
705                                 
706                                 ret = Available_internal(socket, out error);
707
708                                 if (error != 0) 
709                                 {
710                                         throw new SocketException (error);
711                                 }
712
713                                 return(ret);
714                         }
715                 }
716
717 #if !TARGET_JVM
718                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
719                 private extern static void Blocking_internal(IntPtr socket,
720                         bool block,
721                         out int error);
722 #else
723                 private void Blocking_internal(GHSocket socket, bool block,     out int error)
724                 {
725                         socket.Blocking_internal(block, out error);
726                 }
727 #endif
728
729                 public bool Blocking 
730                 {
731                         get 
732                         {
733                                 return(blocking);
734                         }
735                         set 
736                         {
737                                 EnsureStillUsable();
738
739                                 int error;
740                                 
741                                 Blocking_internal(socket, value, out error);
742
743                                 if (error != 0) {
744                                         throw new SocketException (error);
745                                 }
746                                 
747                                 blocking=value;
748                         }
749                 }
750
751                 public bool Connected 
752                 {
753                         get 
754                         {
755                                 return(connected);
756                         }
757                 }
758
759 #if !TARGET_JVM
760                 public IntPtr Handle 
761                 {
762                         get 
763                         {
764                                 return(socket);
765                         }
766                 }
767 #else
768                 public IntPtr Handle 
769                 {
770                         get 
771                         {
772                                 throw new NotImplementedException ();
773                         }
774                 }
775
776                 internal GHSocket GHHandle 
777                 {
778                         get 
779                         {
780                                 return socket;
781                         }
782                 }
783 #endif
784
785 #if !TARGET_JVM
786                 // Returns the local endpoint details in addr and port
787                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
788                 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
789
790                 [MonoTODO("Support non-IP endpoints")]
791                 public EndPoint LocalEndPoint 
792                 {
793                         get 
794                         {
795                                 if (disposed && closed)
796                                         throw new ObjectDisposedException (GetType ().ToString ());
797
798                                 SocketAddress sa;
799                                 int error;
800                                 
801                                 sa=LocalEndPoint_internal(socket, out error);
802
803                                 if (error != 0) {
804                                         throw new SocketException (error);
805                                 }
806
807                                 if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6) {
808                                         // Stupidly, EndPoint.Create() is an
809                                         // instance method
810                                         return new IPEndPoint(0, 0).Create(sa);
811                                 } else if (sa.Family==AddressFamily.Unix &&
812                                            unixendpoint!=null) {
813                                         return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
814                                 } else {
815                                         throw new NotImplementedException();
816                                 }
817                         }
818                 }
819 #else
820                 private EndPoint LocalEndPoint_internal(GHSocket socket, out int error)
821                 {
822                         return socket.LocalEndPoint_internal(out error);
823                 }
824
825                 public EndPoint LocalEndPoint 
826                 {
827                         get 
828                         {
829                                 EnsureStillUsable();
830
831                                 int error;
832
833                                 EndPoint ret = LocalEndPoint_internal(socket, out error);
834
835                                 if (error != 0) 
836                                 {
837                                         throw new SocketException (error);
838                                 }
839
840                                 return ret;
841                         }
842                 }
843 #endif
844
845                         public ProtocolType ProtocolType 
846                 {
847                         get 
848                         {
849                                 return(protocol_type);
850                         }
851                 }
852
853 #if !TARGET_JVM
854                 // Returns the remote endpoint details in addr and port
855                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
856                 private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, out int error);
857
858                 [MonoTODO("Support non-IP endpoints")]
859                 public EndPoint RemoteEndPoint 
860                 {
861                         get 
862                         {
863                                 if (disposed && closed)
864                                         throw new ObjectDisposedException (GetType ().ToString ());
865
866                                 SocketAddress sa;
867                                 int error;
868                                 
869                                 sa=RemoteEndPoint_internal(socket, out error);
870
871                                 if (error != 0) {
872                                         throw new SocketException (error);
873                                 }
874
875                                 if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6 ) {
876                                         // Stupidly, EndPoint.Create() is an
877                                         // instance method
878                                         return new IPEndPoint(0, 0).Create(sa);
879                                 } else if (sa.Family==AddressFamily.Unix &&
880                                            unixendpoint!=null) {
881                                         return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
882                                 } else {
883                                         throw new NotImplementedException();
884                                 }
885                         }
886                 }
887 #else
888                 private EndPoint RemoteEndPoint_internal(GHSocket socket, out int error)
889                 {
890                         return socket.RemoteEndPoint_internal(out error);
891                 }
892
893                 public EndPoint RemoteEndPoint 
894                 {
895                         get 
896                         {
897                                 EnsureStillUsable();
898
899                                 int error;
900
901                                 EndPoint ret = RemoteEndPoint_internal(socket, out error);
902
903                                 if (error != 0) 
904                                 {
905                                         throw new SocketException (error);
906                                 }
907
908                                 return ret;
909                         }
910                 }
911 #endif
912
913                 public SocketType SocketType 
914                 {
915                         get 
916                         {
917                                 return(socket_type);
918                         }
919                 }
920
921                 public static bool SupportsIPv4 
922                 {
923                         get 
924                         {
925                                 CheckProtocolSupport();
926                                 return ipv4Supported == 1;
927                         }
928                 }
929
930                 public static bool SupportsIPv6 
931                 {
932                         get 
933                         {
934                                 CheckProtocolSupport();
935                                 return ipv6Supported == 1;
936                         }
937                 }
938
939                 internal static void CheckProtocolSupport()
940                 {
941                         if(ipv4Supported == -1) 
942                         {
943                                 try  
944                                 {
945                                         Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
946                                         tmp.Close();
947
948                                         ipv4Supported = 1;
949                                 }
950                                 catch 
951                                 {
952                                         ipv4Supported = 0;
953                                 }
954                         }
955
956                         if(ipv6Supported == -1) 
957                         {
958 #if CONFIGURATION_DEP
959                                 SettingsSection config;
960                                 config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection ("system.net/settings");
961                                 if (config != null)
962                                         ipv6Supported = config.Ipv6.Enabled ? -1 : 0;
963 #else
964                                 NetConfig config = (NetConfig)System.Configuration.ConfigurationSettings.GetConfig("system.net/settings");
965
966                                 if(config != null)
967                                         ipv6Supported = config.ipv6Enabled?-1:0;
968 #endif
969                                 if(ipv6Supported != 0) 
970                                 {
971                                         try 
972                                         {
973                                                 Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
974                                                 tmp.Close();
975
976                                                 ipv6Supported = 1;
977                                         }
978                                         catch { }
979                                 }
980                         }
981                 }
982
983 #if !TARGET_JVM
984                 // Creates a new system socket, returning the handle
985                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
986                 private extern static IntPtr Accept_internal(IntPtr sock,
987                         out int error);
988 #else
989                 private GHSocket Accept_internal(GHSocket sock, out int error)
990                 {
991                         return sock.Accept_internal(out error);
992                 }
993 #endif
994
995                 public Socket Accept() 
996                 {
997                         EnsureStillUsable();
998
999                         int error = 0;
1000 #if !TARGET_JVM
1001                         IntPtr sock = (IntPtr) (-1);
1002 #else
1003                         GHSocket sock = null;
1004 #endif
1005                         sock = Accept_internal(socket, out error);
1006                         if (error != 0) {
1007                                 throw new SocketException (error);
1008                         }
1009                         
1010                         Socket accepted = new Socket(this.AddressFamily,
1011                                                      this.SocketType,
1012                                                      this.ProtocolType, sock);
1013
1014                         accepted.Blocking = this.Blocking;
1015                         return(accepted);
1016                 }
1017
1018                 public IAsyncResult BeginAccept(AsyncCallback callback,
1019                         object state) 
1020                 {
1021
1022                         EnsureStillUsable();
1023
1024                         SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
1025                         Worker worker = new Worker (req);
1026                         SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
1027                         sac.BeginInvoke (null, req);
1028                         return(req);
1029                 }
1030
1031                 public IAsyncResult BeginConnect(EndPoint end_point,
1032                         AsyncCallback callback,
1033                         object state) 
1034                 {
1035
1036                         EnsureStillUsable();
1037
1038                         if (end_point == null)
1039                                 throw new ArgumentNullException ("end_point");
1040
1041                         SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1042                         req.EndPoint = end_point;
1043
1044                         // Bug #75154: Connect() should not succeed for .Any addresses.
1045                         if (end_point is IPEndPoint) 
1046                         {
1047                                 IPEndPoint ep = (IPEndPoint) end_point;
1048                                 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) 
1049                                 {
1050                                         req.Complete (new SocketException (10049), true);
1051                                         return req;
1052                                 }
1053                         }
1054
1055                         int error = 0;
1056                         if (!blocking) 
1057                         {
1058 #if !TARGET_JVM
1059                                 SocketAddress serial = end_point.Serialize ();
1060                                 Connect_internal (socket, serial, out error);
1061 #else
1062                                 Connect_internal (socket, end_point, out error);
1063 #endif
1064                                 if (error == 0) 
1065                                 {
1066                                         // succeeded synch
1067                                         connected = true;
1068                                         req.Complete (true);
1069                                 } 
1070                                 else if (error != 10036 && error != 10035) 
1071                                 {
1072                                         // error synch
1073                                         connected = false;
1074                                         req.Complete (new SocketException (error), true);
1075                                 }
1076                         }
1077
1078                         if (blocking || error == 10036 || error == 10035) 
1079                         {
1080                                 // continue asynch
1081                                 connected = false;
1082                                 Worker worker = new Worker (req);
1083                                 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1084                                 sac.BeginInvoke (null, req);
1085                         }
1086
1087                         return(req);
1088                 }
1089
1090                 public IAsyncResult BeginReceive(byte[] buffer, int offset,
1091                         int size,
1092                         SocketFlags socket_flags,
1093                         AsyncCallback callback,
1094                         object state) 
1095                 {
1096
1097                         EnsureStillUsable();
1098
1099                         if (buffer == null)
1100                                 throw new ArgumentNullException ("buffer");
1101
1102                         if (offset < 0 || offset > buffer.Length)
1103                                 throw new ArgumentOutOfRangeException ("offset");
1104
1105                         if (size < 0 || offset + size > buffer.Length)
1106                                 throw new ArgumentOutOfRangeException ("size");
1107
1108                         SocketAsyncResult req;
1109                         lock (readQ) 
1110                         {
1111                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
1112                                 req.Buffer = buffer;
1113                                 req.Offset = offset;
1114                                 req.Size = size;
1115                                 req.SockFlags = socket_flags;
1116                                 readQ.Enqueue (req);
1117                                 if (readQ.Count == 1) 
1118                                 {
1119                                         Worker worker = new Worker (req);
1120                                         SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1121                                         sac.BeginInvoke (null, req);
1122                                 }
1123                         }
1124
1125                         return req;
1126                 }
1127
1128                 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
1129                         int size,
1130                         SocketFlags socket_flags,
1131                         ref EndPoint remote_end,
1132                         AsyncCallback callback,
1133                         object state) 
1134                 {
1135                         EnsureStillUsable();
1136
1137                         if (buffer == null)
1138                                 throw new ArgumentNullException ("buffer");
1139
1140                         if (offset < 0)
1141                                 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1142
1143                         if (size < 0)
1144                                 throw new ArgumentOutOfRangeException ("size must be >= 0");
1145
1146                         if (offset + size > buffer.Length)
1147                                 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1148
1149                         SocketAsyncResult req;
1150                         lock (readQ) 
1151                         {
1152                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
1153                                 req.Buffer = buffer;
1154                                 req.Offset = offset;
1155                                 req.Size = size;
1156                                 req.SockFlags = socket_flags;
1157                                 req.EndPoint = remote_end;
1158                                 readQ.Enqueue (req);
1159                                 if (readQ.Count == 1) 
1160                                 {
1161                                         Worker worker = new Worker (req);
1162                                         SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
1163                                         sac.BeginInvoke (null, req);
1164                                 }
1165                         }
1166                         return req;
1167                 }
1168
1169                 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
1170                         AsyncCallback callback, object state)
1171                 {
1172                         EnsureStillUsable();
1173
1174                         if (buffer == null)
1175                                 throw new ArgumentNullException ("buffer");
1176
1177                         if (offset < 0)
1178                                 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1179
1180                         if (size < 0)
1181                                 throw new ArgumentOutOfRangeException ("size must be >= 0");
1182
1183                         if (offset + size > buffer.Length)
1184                                 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1185
1186                         SocketAsyncResult req;
1187                         lock (writeQ) 
1188                         {
1189                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
1190                                 req.Buffer = buffer;
1191                                 req.Offset = offset;
1192                                 req.Size = size;
1193                                 req.SockFlags = socket_flags;
1194                                 writeQ.Enqueue (req);
1195                                 if (writeQ.Count == 1) 
1196                                 {
1197                                         Worker worker = new Worker (req);
1198                                         SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1199                                         sac.BeginInvoke (null, req);
1200                                 }
1201                         }
1202                         return req;
1203                 }
1204
1205                 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1206                         int size,
1207                         SocketFlags socket_flags,
1208                         EndPoint remote_end,
1209                         AsyncCallback callback,
1210                         object state) 
1211                 {
1212                         EnsureStillUsable();
1213
1214                         if (buffer == null)
1215                                 throw new ArgumentNullException ("buffer");
1216
1217                         if (offset < 0)
1218                                 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1219
1220                         if (size < 0)
1221                                 throw new ArgumentOutOfRangeException ("size must be >= 0");
1222
1223                         if (offset + size > buffer.Length)
1224                                 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1225
1226                         SocketAsyncResult req;
1227                         lock (writeQ) 
1228                         {
1229                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1230                                 req.Buffer = buffer;
1231                                 req.Offset = offset;
1232                                 req.Size = size;
1233                                 req.SockFlags = socket_flags;
1234                                 req.EndPoint = remote_end;
1235                                 writeQ.Enqueue (req);
1236                                 if (writeQ.Count == 1) 
1237                                 {
1238                                         Worker worker = new Worker (req);
1239                                         SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
1240                                         sac.BeginInvoke (null, req);
1241                                 }
1242                         }
1243                         return req;
1244                 }
1245
1246 #if !TARGET_JVM
1247                 // Creates a new system socket, returning the handle
1248                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1249                 private extern static void Bind_internal(IntPtr sock,
1250                                                          SocketAddress sa,
1251                                                          out int error);
1252
1253                 public void Bind(EndPoint local_end) 
1254                 {
1255                         if (disposed && closed)
1256                                 throw new ObjectDisposedException (GetType ().ToString ());
1257
1258                         if(local_end==null) {
1259                                 throw new ArgumentNullException("local_end");
1260                         }
1261                         
1262                         int error;
1263                         
1264                         Bind_internal(socket, local_end.Serialize(),
1265                                       out error);
1266
1267                         if (error != 0) {
1268                                 throw new SocketException (error);
1269                         }
1270                 }
1271 #else
1272                 private void Bind_internal(GHSocket sock,
1273                         EndPoint sa,
1274                         out int error)
1275                 {
1276                         sock.Bind_internal(sa, out error);
1277                 }
1278
1279                 public void Bind(EndPoint local_end) 
1280                 {
1281                         EnsureStillUsable();
1282
1283                         if(local_end==null) {
1284                                 throw new ArgumentNullException("local_end");
1285                         }
1286                         
1287                         int error;
1288                         
1289                         Bind_internal(socket, local_end,
1290                                       out error);
1291
1292                         if (error != 0) {
1293                                 throw new SocketException (error);
1294                         }
1295                 }
1296 #endif
1297
1298 #if !TARGET_JVM
1299                 // Closes the socket
1300                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1301                 private extern static void Close_internal(IntPtr socket,
1302                                                           out int error);
1303 #else
1304                 private void Close_internal(GHSocket socket, out int error)
1305                 {
1306                         socket.Close_internal(out error);
1307                 }
1308 #endif  
1309
1310                 public void Close() 
1311                 {
1312                         ((IDisposable) this).Dispose ();
1313                 }
1314
1315 #if !TARGET_JVM
1316                 // Connects to the remote address
1317                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1318                 private extern static void Connect_internal(IntPtr sock,
1319                                                             SocketAddress sa,
1320                                                             out int error);
1321 #else
1322                 private void Connect_internal(GHSocket sock,
1323                         EndPoint sa,
1324                         out int error)
1325                 {
1326                         sock.Connect_internal(sa, out error);
1327                 }
1328 #endif
1329
1330                 public void Connect(EndPoint remote_end) 
1331                 {
1332                         EnsureStillUsable();
1333
1334                         if(remote_end==null) {
1335                                 throw new ArgumentNullException("remote_end");
1336                         }
1337
1338                         if (remote_end is IPEndPoint) {
1339                                 IPEndPoint ep = (IPEndPoint) remote_end;
1340                                 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
1341                                         throw new SocketException (10049);
1342                         }
1343
1344                         int error = 0;
1345
1346 #if !TARGET_JVM
1347                                 Connect_internal (socket, remote_end.Serialize(), out error);
1348 #else
1349                                 Connect_internal (socket, remote_end, out error);
1350 #endif
1351                         if (error != 0) {
1352                                 throw new SocketException (error);
1353                         }
1354                         
1355                         connected=true;
1356                 }       
1357         
1358 #if TARGET_JVM
1359                 public void ChangeToSSL()
1360                 {
1361                         try
1362                         {
1363                                 GHSocket tmp = socket.ChangeToSSL(null);
1364                                 if (tmp != null)
1365                                 {
1366                                         socket = tmp;
1367                                 }
1368                         }
1369                         catch (Exception e)
1370                         {
1371 #if DEBUG 
1372                                 Console.WriteLine("Caught exception during ChangeToSSL: {0}, {1}", e.GetType(), e.Message);
1373 #endif
1374                                 throw new SocketException(10045);
1375                         }
1376                 }
1377 #endif          
1378                 
1379                 public Socket EndAccept(IAsyncResult result) 
1380                 {
1381                         EnsureStillUsable();
1382
1383                         if (result == null)
1384                                 throw new ArgumentNullException ("result");
1385
1386                         SocketAsyncResult req = result as SocketAsyncResult;
1387                         if (req == null)
1388                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1389
1390                         if (!result.IsCompleted)
1391                                 result.AsyncWaitHandle.WaitOne();
1392
1393                         req.CheckIfThrowDelayedException();
1394                         return req.Socket;
1395                 }
1396
1397                 public void EndConnect(IAsyncResult result) {
1398                         EnsureStillUsable();
1399
1400                         if (result == null)
1401                                 throw new ArgumentNullException ("result");
1402
1403                         SocketAsyncResult req = result as SocketAsyncResult;
1404                         if (req == null)
1405                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1406
1407                         if (!result.IsCompleted)
1408                                 result.AsyncWaitHandle.WaitOne();
1409
1410                         req.CheckIfThrowDelayedException();
1411                 }
1412
1413                 [MonoNotSupported ("")]
1414                 public void EndDisconnect (IAsyncResult asyncResult)
1415                 {
1416                         throw new NotImplementedException ();
1417                 }
1418
1419                 public int EndReceive(IAsyncResult result) {
1420                         EnsureStillUsable();
1421
1422                         if (result == null)
1423                                 throw new ArgumentNullException ("result");
1424
1425                         SocketAsyncResult req = result as SocketAsyncResult;
1426                         if (req == null)
1427                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1428
1429                         if (!result.IsCompleted)
1430                                 result.AsyncWaitHandle.WaitOne();
1431
1432                         req.CheckIfThrowDelayedException();
1433                         return req.Total;
1434                 }
1435
1436                 public int EndReceiveFrom(IAsyncResult result,
1437                                           ref EndPoint end_point) 
1438         {
1439                         EnsureStillUsable();
1440
1441                         if (result == null)
1442                                 throw new ArgumentNullException ("result");
1443
1444                         SocketAsyncResult req = result as SocketAsyncResult;
1445                         if (req == null)
1446                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1447
1448                         if (!result.IsCompleted)
1449                                 result.AsyncWaitHandle.WaitOne();
1450
1451                         req.CheckIfThrowDelayedException();
1452                         end_point = req.EndPoint;
1453                         return req.Total;
1454                 }
1455
1456                 public int EndSend(IAsyncResult result) {
1457                         EnsureStillUsable();
1458
1459                         if (result == null)
1460                                 throw new ArgumentNullException ("result");
1461
1462                         SocketAsyncResult req = result as SocketAsyncResult;
1463                         if (req == null)
1464                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1465
1466                         if (!result.IsCompleted)
1467                                 result.AsyncWaitHandle.WaitOne();
1468
1469                         req.CheckIfThrowDelayedException();
1470                         return req.Total;
1471                 }
1472
1473                 public int EndSendTo(IAsyncResult result) {
1474                         EnsureStillUsable();
1475
1476                         if (result == null)
1477                                 throw new ArgumentNullException ("result");
1478
1479                         SocketAsyncResult req = result as SocketAsyncResult;
1480                         if (req == null)
1481                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1482
1483                         if (!result.IsCompleted)
1484                                 result.AsyncWaitHandle.WaitOne();
1485
1486                         req.CheckIfThrowDelayedException();
1487                         return req.Total;
1488                 }
1489
1490 #if !TARGET_JVM
1491                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1492                 private extern static void GetSocketOption_obj_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, out object obj_val, out int error);
1493                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1494                 private extern static void GetSocketOption_arr_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val, out int error);
1495 #else
1496                 private void GetSocketOption_obj_internal(GHSocket socket, SocketOptionLevel level, 
1497                         SocketOptionName name, out object obj_val, out int error)
1498                 {
1499                         EnsureStillUsable();
1500
1501             socket.GetSocketOption_obj_internal(level, name, out obj_val, out error);
1502                 }
1503                 private void GetSocketOption_arr_internal(GHSocket socket, SocketOptionLevel level, 
1504                         SocketOptionName name, ref byte[] byte_val, out int error)
1505                 {
1506                         EnsureStillUsable();
1507
1508             socket.GetSocketOption_arr_internal(level, name, ref byte_val, out error);
1509                 }
1510 #endif
1511
1512                 public object GetSocketOption(SocketOptionLevel level,
1513                                               SocketOptionName name) {
1514                         object obj_val;
1515                         int error;
1516                         
1517                         GetSocketOption_obj_internal(socket, level, name,
1518                                                      out obj_val, out error);
1519
1520                         if (error != 0) {
1521                                 throw new SocketException (error);
1522                         }
1523                         
1524                         if(name==SocketOptionName.Linger) {
1525                                 return((LingerOption)obj_val);
1526                         } else if (name==SocketOptionName.AddMembership ||
1527                                    name==SocketOptionName.DropMembership) {
1528                                 return((MulticastOption)obj_val);
1529                         } else if (obj_val is int) {
1530                                 return((int)obj_val);
1531                         } else {
1532                                 return(obj_val);
1533                         }
1534                 }
1535
1536                 public void GetSocketOption(SocketOptionLevel level,
1537                                             SocketOptionName name,
1538                                             byte[] opt_value) {
1539                         int error;
1540                         
1541                         GetSocketOption_arr_internal(socket, level, name,
1542                                                      ref opt_value, out error);
1543
1544                         if (error != 0) {
1545                                 throw new SocketException (error);
1546                         }
1547                 }
1548
1549                 public byte[] GetSocketOption(SocketOptionLevel level,
1550                                               SocketOptionName name,
1551                                               int length) {
1552                         byte[] byte_val=new byte[length];
1553                         int error;
1554                         
1555                         GetSocketOption_arr_internal(socket, level, name,
1556                                                      ref byte_val, out error);
1557
1558                         if (error != 0) {
1559                                 throw new SocketException (error);
1560                         }
1561
1562                         return(byte_val);
1563                 }
1564
1565 #if !TARGET_JVM
1566                 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
1567                 // common options between UNIX and Winsock are FIONREAD,
1568                 // FIONBIO and SIOCATMARK. Anything else will depend on the
1569                 // system.
1570                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1571                 extern static int WSAIoctl (IntPtr sock, int ioctl_code,
1572                                             byte [] input, byte [] output,
1573                                             out int error);
1574 #else
1575                 int WSAIoctl (GHSocket sock, int ioctl_code,
1576                         byte [] input, byte [] output,
1577                         out int error)
1578                 {
1579                         return sock.WSAIoctl(ioctl_code, input, output, out error);
1580                 }
1581 #endif
1582
1583                 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
1584                 {
1585                         if (disposed)
1586                                 throw new ObjectDisposedException (GetType ().ToString ());
1587
1588                         int error;
1589                         int result = WSAIoctl (socket, ioctl_code, in_value,
1590                                                out_value, out error);
1591
1592                         if (error != 0) {
1593                                 throw new SocketException (error);
1594                         }
1595                         
1596                         if (result == -1)
1597                                 throw new InvalidOperationException ("Must use Blocking property instead.");
1598
1599                         return result;
1600                 }
1601
1602                 [MonoNotSupported ("")]
1603                 public int IOControl (IOControlCode ioControlCode, byte [] optionInValue, byte [] optionOutValue)
1604                 {
1605                         throw new NotImplementedException ();
1606                 }
1607
1608 #if !TARGET_JVM
1609                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1610                 private extern static void Listen_internal(IntPtr sock,
1611                                                            int backlog,
1612                                                            out int error);
1613 #else
1614                 private void Listen_internal(GHSocket sock,
1615                         int backlog,
1616                         out int error)
1617                 {
1618                         EnsureStillUsable();
1619
1620                         sock.Listen_internal(backlog, out error);
1621                 }
1622 #endif
1623
1624                 public void Listen(int backlog) 
1625                 {
1626                         int error;
1627                         
1628                         Listen_internal(socket, backlog, out error);
1629
1630                         if (error != 0) {
1631                                 throw new SocketException (error);
1632                         }
1633                 }
1634
1635 #if !TARGET_JVM
1636                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1637                 extern static bool Poll_internal (IntPtr socket, SelectMode mode, int timeout, out int error);
1638 #else
1639                 bool Poll_internal (GHSocket socket, SelectMode mode, int timeout, out int error)
1640                 {
1641                         return socket.Poll_internal(mode, timeout, this, out error);
1642                 }
1643 #endif
1644
1645                 public bool Poll(int time_us, SelectMode mode) 
1646                 {
1647                         EnsureStillUsable();
1648
1649                         if (mode != SelectMode.SelectRead &&
1650                             mode != SelectMode.SelectWrite &&
1651                             mode != SelectMode.SelectError)
1652                                 throw new NotSupportedException ("'mode' parameter is not valid.");
1653
1654                         int error;
1655                         bool result = Poll_internal (socket, mode, time_us, out error);
1656                         if (error != 0)
1657                                 throw new SocketException (error);
1658                         
1659                         if (result == true) {
1660                                 /* Update the connected state; for
1661                                  * non-blocking Connect()s this is
1662                                  * when we can find out that the
1663                                  * connect succeeded.
1664                                  */
1665                                 connected = true;
1666                         }
1667
1668                         return result;
1669                 }
1670                 
1671                 public int Receive (byte [] buf)
1672                 {
1673                         EnsureStillUsable();
1674
1675                         if (buf == null)
1676                                 throw new ArgumentNullException ("buf");
1677
1678                         return Receive_nochecks (buf, 0, buf.Length, SocketFlags.None);
1679                 }
1680
1681                 public int Receive (byte [] buf, SocketFlags flags)
1682                 {
1683                         EnsureStillUsable();
1684
1685                         if (buf == null)
1686                                 throw new ArgumentNullException ("buf");
1687
1688                         return Receive_nochecks (buf, 0, buf.Length, flags);
1689                 }
1690
1691                 public int Receive (byte [] buf, int size, SocketFlags flags)
1692                 {
1693                         EnsureStillUsable();
1694
1695                         if (buf == null)
1696                                 throw new ArgumentNullException ("buf");
1697
1698                         if (size < 0 || size > buf.Length)
1699                                 throw new ArgumentOutOfRangeException ("size");
1700
1701                         return Receive_nochecks (buf, 0, size, flags);
1702                 }
1703
1704 #if !TARGET_JVM
1705                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1706                 private extern static int Receive_internal(IntPtr sock,
1707                                                            byte[] buffer,
1708                                                            int offset,
1709                                                            int count,
1710                                                            SocketFlags flags,
1711                                                            out int error);
1712 #else
1713                 private int Receive_internal(GHSocket sock,
1714                         byte[] buffer,
1715                         int offset,
1716                         int count,
1717                         SocketFlags flags,
1718                         out int error)
1719                 {
1720                         return sock.Receive_internal(buffer, offset, count, flags, out error);
1721                 }
1722 #endif
1723
1724                 public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
1725                 {
1726                         EnsureStillUsable();
1727
1728                         if(buf==null) 
1729                                 throw new ArgumentNullException ("buf");
1730
1731                         if (offset < 0 || offset > buf.Length)
1732                                 throw new ArgumentOutOfRangeException ("offset");
1733
1734                         if (size < 0 || offset + size > buf.Length)
1735                                 throw new ArgumentOutOfRangeException ("size");
1736
1737                         return Receive_nochecks (buf, offset, size, flags);
1738                 }
1739                         
1740                 int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
1741                 {
1742                         int ret, error;
1743                         ret = Receive_internal (socket, buf, offset, size, flags, out error);
1744
1745                         if(error != 0) {
1746                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
1747                                 connected=false;
1748
1749                                 throw new SocketException (error);
1750                         }
1751                         
1752                         connected=true;
1753
1754                         return ret;
1755                 }
1756
1757                 public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
1758                 {
1759                         if (buf == null)
1760                                 throw new ArgumentNullException ("buf");
1761
1762                         if (remote_end == null)
1763                                 throw new ArgumentNullException ("remote_end");
1764
1765                         return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
1766                 }
1767
1768                 public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
1769                 {
1770                         if (buf == null)
1771                                 throw new ArgumentNullException ("buf");
1772
1773                         if (remote_end == null)
1774                                 throw new ArgumentNullException ("remote_end");
1775
1776
1777                         return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
1778                 }
1779
1780                 public int ReceiveFrom(byte[] buf, int size, SocketFlags flags,
1781                                         ref EndPoint remote_end)
1782                 {
1783                         if (buf == null)
1784                                 throw new ArgumentNullException ("buf");
1785
1786                         if (remote_end == null)
1787                                 throw new ArgumentNullException ("remote_end");
1788
1789                         if (size < 0 || size > buf.Length)
1790                                 throw new ArgumentOutOfRangeException ("size");
1791
1792                         return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
1793                 }
1794
1795 #if !TARGET_JVM
1796                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1797                 private extern static int RecvFrom_internal(IntPtr sock,
1798                                                             byte[] buffer,
1799                                                             int offset,
1800                                                             int count,
1801                                                             SocketFlags flags,
1802                                                             ref SocketAddress sockaddr,
1803                                                             out int error);
1804 #else
1805                 private int RecvFrom_internal(GHSocket sock,
1806                         byte[] buffer,
1807                         int offset,
1808                         int count,
1809                         SocketFlags flags,
1810                         ref SocketAddress sockaddr,
1811                         out int error)
1812                 {
1813                         return sock.RecvFrom_internal(buffer, offset, count, flags, ref sockaddr, out error);
1814                 }
1815
1816 #endif
1817
1818                 public int ReceiveFrom(byte[] buf, int offset, int size, SocketFlags flags,
1819                                        ref EndPoint remote_end) 
1820                 {
1821                         EnsureStillUsable();
1822
1823                         if (buf == null)
1824                                 throw new ArgumentNullException ("buf");
1825
1826                         if (remote_end == null)
1827                                 throw new ArgumentNullException ("remote_end");
1828
1829                         if (offset < 0 || offset > buf.Length)
1830                                 throw new ArgumentOutOfRangeException ("offset");
1831
1832                         if (size < 0 || offset + size > buf.Length)
1833                                 throw new ArgumentOutOfRangeException ("size");
1834
1835                         return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
1836                 }
1837
1838                 int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
1839                                           ref EndPoint remote_end)
1840                 {
1841                         EnsureStillUsable();
1842
1843                         SocketAddress sockaddr=remote_end.Serialize();
1844                         int cnt, error;
1845
1846                         cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
1847
1848                         if (error != 0) {
1849                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
1850                                 connected=false;
1851
1852                                 throw new SocketException (error);
1853                         }
1854
1855                         connected=true;
1856                         
1857                         // If sockaddr is null then we're a connection
1858                         // oriented protocol and should ignore the
1859                         // remote_end parameter (see MSDN
1860                         // documentation for Socket.ReceiveFrom(...) )
1861                         
1862                         if ( sockaddr != null ) {
1863                         // Stupidly, EndPoint.Create() is an
1864                         // instance method
1865                         remote_end=remote_end.Create(sockaddr);
1866                         }
1867
1868                         return cnt;
1869                 }
1870
1871                 public int Send (byte [] buf)
1872                 {
1873                     EnsureStillUsable();
1874
1875                     if (buf == null)
1876                                 throw new ArgumentNullException ("buf");
1877
1878                     return Send_nochecks (buf, 0, buf.Length, SocketFlags.None);
1879                 }
1880
1881                 public int Send (byte [] buf, SocketFlags flags)
1882                 {
1883                     EnsureStillUsable();
1884
1885                     if (buf == null)
1886                                 throw new ArgumentNullException ("buf");
1887
1888                     return Send_nochecks (buf, 0, buf.Length, flags);
1889                 }
1890
1891                 public int Send (byte [] buf, int size, SocketFlags flags)
1892                 {
1893                         EnsureStillUsable();
1894
1895                         if (buf == null)
1896                                 throw new ArgumentNullException ("buf");
1897
1898                         if (size < 0 || size > buf.Length)
1899                                 throw new ArgumentOutOfRangeException ("size");
1900
1901                         return Send_nochecks (buf, 0, size, flags);
1902                 }
1903
1904                 [MonoNotSupported ("")]
1905                 public int Send (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
1906                 {
1907                         throw new NotImplementedException ();
1908                 }
1909
1910                 [MonoNotSupported ("")]
1911                 public int Send (IList<ArraySegment<byte>> buffers)
1912                 {
1913                         throw new NotImplementedException ();
1914                 }
1915
1916                 [MonoNotSupported ("")]
1917                 public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
1918                 {
1919                         throw new NotImplementedException ();
1920                 }
1921
1922                 //[CLSCompliantAttribute (false)]
1923                 [MonoNotSupported ("")]
1924                 public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
1925                 {
1926                         throw new NotImplementedException ();
1927                 }
1928
1929                 [MonoNotSupported ("")]
1930                 public int Receive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
1931                 {
1932                         throw new NotImplementedException ();
1933                 }
1934
1935                 [MonoNotSupported ("")]
1936                 public int Receive (IList<ArraySegment<byte>> buffers)
1937                 {
1938                         throw new NotImplementedException ();
1939                 }
1940
1941                 //[CLSCompliantAttribute (false)]
1942                 [MonoNotSupported ("")]
1943                 public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
1944                 {
1945                         throw new NotImplementedException ();
1946                 }
1947
1948                 //[CLSCompliantAttribute (false)]
1949                 [MonoNotSupported ("")]
1950                 public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
1951                 {
1952                         throw new NotImplementedException ();
1953                 }
1954
1955                 [MonoNotSupported ("")]
1956                 public int ReceiveMessageFrom (byte [] buffer, int offset, int size, ref SocketFlags socketFlags, ref EndPoint remoteEP, out IPPacketInformation ipPacketInformation)
1957                 {
1958                         throw new NotImplementedException ();
1959                 }
1960
1961                 [MonoNotSupported ("")]
1962                 public IAsyncResult BeginReceiveMessageFrom (byte [] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP, AsyncCallback callback, Object state)
1963                 {
1964                         throw new NotImplementedException ();
1965                 }
1966
1967                 [MonoNotSupported ("")]
1968                 public int EndReceiveMessageFrom (IAsyncResult asyncResult, ref SocketFlags socketFlags, ref EndPoint endPoint, out IPPacketInformation ipPacketInformation)
1969                 {
1970                         throw new NotImplementedException ();
1971                 }
1972
1973 #if !TARGET_JVM
1974                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1975                 private extern static int Send_internal(IntPtr sock,
1976                                                         byte[] buf, int offset,
1977                                                         int count,
1978                                                         SocketFlags flags,
1979                                                         out int error);
1980 #else
1981                 private int Send_internal(GHSocket sock,
1982                         byte[] buf, int offset,
1983                         int count,
1984                         SocketFlags flags,
1985                         out int error)
1986                 {
1987                         return sock.Send_internal(buf, offset, count, flags, out error);
1988                 }
1989 #endif
1990
1991                 public int Send (byte[] buf, int offset, int size, SocketFlags flags)
1992                 {
1993                         EnsureStillUsable();
1994
1995                         if (buf == null)
1996                                 throw new ArgumentNullException ("buffer");
1997
1998                         if (offset < 0 || offset > buf.Length)
1999                                 throw new ArgumentOutOfRangeException ("offset");
2000
2001                         if (size < 0 || offset + size > buf.Length)
2002                                 throw new ArgumentOutOfRangeException ("size");
2003
2004                         return Send_nochecks (buf, offset, size, flags);
2005                 }
2006
2007                 int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
2008                 {
2009                         if (size == 0)
2010                                 return 0;
2011
2012                         int ret, error;
2013
2014                         ret = Send_internal (socket, buf, offset, size, flags, out error);
2015
2016                         if (error != 0) {
2017                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
2018                                     connected = false;
2019
2020                                 throw new SocketException (error);
2021                         }
2022                         connected = true;
2023
2024                         return ret;
2025                 }
2026
2027                 public int SendTo (byte [] buffer, EndPoint remote_end)
2028                 {
2029                         EnsureStillUsable();
2030
2031                         if (buffer == null)
2032                                 throw new ArgumentNullException ("buffer");
2033
2034                         if (remote_end == null)
2035                                 throw new ArgumentNullException ("remote_end");
2036
2037                         return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2038                 }
2039
2040                 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2041                 {
2042                         EnsureStillUsable();
2043
2044                         if (buffer == null)
2045                                 throw new ArgumentNullException ("buffer");
2046
2047                         if (remote_end == null)
2048                                 throw new ArgumentNullException ("remote_end");
2049                                 
2050                         return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2051                 }
2052
2053                 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2054                 {
2055                         EnsureStillUsable();
2056
2057                         if (buffer == null)
2058                                 throw new ArgumentNullException ("buffer");
2059
2060                         if (remote_end == null)
2061                                 throw new ArgumentNullException ("remote_end");
2062
2063                         if (size < 0 || size > buffer.Length)
2064                                 throw new ArgumentOutOfRangeException ("size");
2065
2066                         return SendTo_nochecks (buffer, 0, size, flags, remote_end);
2067                 }
2068
2069 #if !TARGET_JVM
2070                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2071                 private extern static int SendTo_internal(IntPtr sock,
2072                                                           byte[] buffer,
2073                                                           int offset,
2074                                                           int count,
2075                                                           SocketFlags flags,
2076                                                           SocketAddress sa,
2077                                                           out int error);
2078 #else
2079                 private int SendTo_internal(GHSocket sock,
2080                         byte[] buffer,
2081                         int offset,
2082                         int count,
2083                         SocketFlags flags,
2084                         SocketAddress sa,
2085                         out int error)
2086                 {
2087                         return sock.SendTo_internal(buffer, offset, count, flags, sa, out error);
2088                 }
2089 #endif
2090
2091                 public int SendTo(byte[] buffer, int offset, int size, SocketFlags flags, 
2092                            EndPoint remote_end) 
2093                 {
2094                         EnsureStillUsable();
2095
2096                         if (buffer == null)
2097                                 throw new ArgumentNullException ("buffer");
2098
2099                         if (remote_end == null)
2100                                 throw new ArgumentNullException("remote_end");
2101
2102                         if (offset < 0 || offset > buffer.Length)
2103                                 throw new ArgumentOutOfRangeException ("offset");
2104
2105                         if (size < 0 || offset + size > buffer.Length)
2106                                 throw new ArgumentOutOfRangeException ("size");
2107
2108                         return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2109                 }
2110
2111                 int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
2112                                    EndPoint remote_end)
2113                 {
2114                         SocketAddress sockaddr=remote_end.Serialize();
2115
2116                         int ret, error;
2117
2118                         ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
2119
2120                         if (error != 0) {
2121                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
2122                                 connected=false;
2123
2124                                 throw new SocketException (error);
2125                         }
2126
2127                         connected=true;
2128
2129                         return ret;
2130                 }
2131
2132 #if !TARGET_JVM
2133                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2134                 private extern static void SetSocketOption_internal (IntPtr socket, SocketOptionLevel level,
2135                                                                      SocketOptionName name, object obj_val,
2136                                                                      byte [] byte_val, int int_val,
2137                                                                      out int error);
2138 #else
2139                 private void SetSocketOption_internal (GHSocket socket, SocketOptionLevel level,
2140                         SocketOptionName name, object obj_val,
2141                         byte [] byte_val, int int_val,
2142                         out int error)
2143                 {
2144                         socket.SetSocketOption_internal(level, name, obj_val, byte_val, int_val, out error);
2145                 }
2146 #endif
2147
2148                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, byte[] opt_value)
2149                 {
2150                         EnsureStillUsable();
2151
2152                         int error;
2153                         
2154                         SetSocketOption_internal(socket, level, name, null,
2155                                                  opt_value, 0, out error);
2156
2157                         if (error != 0) {
2158                                 throw new SocketException (error);
2159                         }
2160                 }
2161
2162                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, int opt_value)
2163                 {
2164                         EnsureStillUsable();
2165
2166                         int error;
2167                         
2168                         SetSocketOption_internal(socket, level, name, null,
2169                                                  null, opt_value, out error);
2170
2171                         if (error != 0) {
2172                                 throw new SocketException (error);
2173                         }
2174                 }
2175
2176                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, object opt_value)
2177                 {
2178
2179                         EnsureStillUsable();
2180
2181                         if(opt_value==null) {
2182                                 throw new ArgumentNullException();
2183                         }
2184                         
2185                         int error;
2186                         /* From MS documentation on SetSocketOption: "For an
2187                          * option with a Boolean data type, specify a nonzero
2188                          * value to enable the option, and a zero value to
2189                          * disable the option."
2190                          * Booleans are only handled in 2.0
2191                          */
2192
2193                         if (opt_value is System.Boolean) {
2194                                 bool bool_val = (bool) opt_value;
2195                                 int int_val = (bool_val) ? 1 : 0;
2196
2197                                 SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
2198                         } else {
2199                                 SetSocketOption_internal (socket, level, name, opt_value, null, 0, out error);
2200                         }
2201
2202                         if (error != 0)
2203                                 throw new SocketException (error);
2204                 }
2205
2206                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, bool optionValue) {
2207                         EnsureStillUsable();
2208
2209                         int error;
2210                         int int_val = (optionValue) ? 1 : 0;
2211                         SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
2212                         if (error != 0)
2213                                 throw new SocketException (error);
2214                 }
2215
2216 #if !TARGET_JVM
2217                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2218                 private extern static void Shutdown_internal(IntPtr socket, SocketShutdown how, out int error);
2219 #else
2220                 private void Shutdown_internal(GHSocket socket, SocketShutdown how, out int error)
2221                 {
2222                         socket.Shutdown_internal(how, out error);
2223                 }
2224 #endif
2225
2226                 public void Shutdown(SocketShutdown how) 
2227                 {
2228                         EnsureStillUsable();
2229
2230                         int error;
2231                         
2232                         Shutdown_internal(socket, how, out error);
2233
2234                         if (error != 0) {
2235                                 throw new SocketException (error);
2236                         }
2237                 }
2238
2239 #if !TARGET_JVM
2240                 public override int GetHashCode ()
2241                 { 
2242                         return (int) socket; 
2243                 }
2244 #else
2245                 public override int GetHashCode ()
2246                 { 
2247                         if (socket == null)
2248                                 return -1;
2249
2250                         return socket.GetHashCode(); 
2251                 }
2252 #endif
2253
2254 #if !TARGET_JVM
2255                 protected virtual void Dispose (bool explicitDisposing)
2256                 {
2257                         if (disposed)
2258                                 return;
2259
2260                         disposed = true;
2261                         connected = false;
2262                         if ((int) socket != -1) 
2263                         {
2264                                 int error;
2265                                 closed = true;
2266                                 IntPtr x = socket;
2267                                 socket = (IntPtr) (-1);
2268                                 Close_internal (x, out error);
2269                                 if (blocking_thread != null) 
2270                                 {
2271                                         blocking_thread.Abort ();
2272                                         blocking_thread = null;
2273                                 }
2274
2275                                 if (error != 0)
2276                                         throw new SocketException (error);
2277                         }
2278                 }
2279 #else
2280         private void EnsureStillUsable()
2281         {
2282             if (disposed && closed)
2283                 throw new ObjectDisposedException(this.GetType().ToString());
2284         }
2285         protected virtual void Dispose (bool explicitDisposing)
2286                 {
2287                         if (disposed)
2288                                 return;
2289
2290                         disposed = true;
2291                         connected = false;
2292                         if (socket != null) 
2293                         {
2294                                 int error;
2295                                 closed = true;
2296                                 GHSocket x = socket;
2297                                 socket = null;
2298                                 Close_internal (x, out error);
2299
2300                                 if (error != 0)
2301                                         throw new SocketException (error);
2302                         }
2303                 }
2304 #endif
2305
2306         #region .Net 2.0 properties and methods
2307
2308             #region Properties
2309         [MonoTODO]
2310         public int ReceiveBufferSize
2311         {
2312             get { throw new NotImplementedException(); }
2313             set { throw new NotImplementedException(); }
2314         }
2315
2316         [MonoTODO]
2317         public int SendBufferSize
2318         {
2319             get { throw new NotImplementedException(); }
2320             set { throw new NotImplementedException(); }
2321         }
2322
2323         [MonoTODO]
2324         public bool UseOnlyOverlappedIO
2325         {
2326             get { throw new NotImplementedException(); }
2327             set { throw new NotImplementedException(); }
2328         }
2329         
2330         [MonoTODO]
2331         public bool NoDelay
2332         {
2333             get { throw new NotImplementedException(); }
2334             set { throw new NotImplementedException(); }
2335         }
2336
2337         [MonoTODO]
2338         public bool IsBound
2339         {
2340             get { throw new NotImplementedException(); }
2341         }
2342
2343         [MonoTODO]
2344         public bool ExclusiveAddressUse
2345         {
2346             get { throw new NotImplementedException(); }
2347             set { throw new NotImplementedException(); }
2348         }
2349
2350         [MonoTODO("udp sockets are not supported")]
2351         public bool DontFragment 
2352         {
2353             get { throw new NotImplementedException(); }
2354             set { throw new NotImplementedException(); }
2355         }
2356
2357         [MonoTODO]
2358         public bool EnableBroadcast
2359         {
2360             get { throw new NotImplementedException(); }
2361             set { throw new NotImplementedException(); }
2362         }
2363
2364         [MonoTODO]
2365         public bool MulticastLoopback
2366         {
2367             get { throw new NotImplementedException(); }
2368             set { throw new NotImplementedException(); }
2369         }
2370
2371         [MonoTODO]
2372         public short Ttl
2373         {
2374             get { throw new NotImplementedException(); }
2375             set { throw new NotImplementedException(); }
2376         }
2377
2378         [MonoTODO]
2379         public int ReceiveTimeout
2380         {
2381             get { throw new NotImplementedException(); }
2382             set { throw new NotImplementedException(); }
2383         }
2384
2385         [MonoTODO]
2386         public int SendTimeout
2387         {
2388             get { throw new NotImplementedException(); }
2389             set { throw new NotImplementedException(); }
2390         }
2391             
2392             #endregion //Properties
2393
2394             #region Methods
2395
2396         [MonoTODO]
2397         public IAsyncResult BeginConnect(IPAddress address, int port,
2398                                         AsyncCallback requestCallback,
2399                                         object state)
2400         {
2401             throw new NotImplementedException();
2402         }
2403
2404         [MonoTODO]
2405         public IAsyncResult BeginConnect(IPAddress[] addresses, int port,
2406                                         AsyncCallback requestCallback,
2407                                         object state)
2408         {
2409             throw new NotImplementedException();
2410         }
2411
2412         [MonoTODO]
2413         public IAsyncResult BeginConnect(string host, int port,
2414                                         AsyncCallback requestCallback,
2415                                         object state)
2416         {
2417             throw new NotImplementedException();
2418         }
2419
2420         [MonoTODO]
2421         public IAsyncResult BeginAccept(int receiveSize, AsyncCallback callback, object state)
2422         {
2423             throw new NotImplementedException();
2424         }
2425
2426         [MonoTODO]
2427         public IAsyncResult BeginAccept( Socket acceptSocket,int receiveSize,
2428                                         AsyncCallback callback, object state)
2429         {
2430             throw new NotImplementedException();
2431         }
2432
2433                 [MonoNotSupported ("")]
2434                 public Socket EndAccept (out byte [] buffer, IAsyncResult asyncResult)
2435                 {
2436                         throw new NotImplementedException ();
2437                 }
2438
2439                 [MonoNotSupported ("")]
2440                 public Socket EndAccept (out byte [] buffer, out int bytesTransferred, IAsyncResult asyncResult)
2441                 {
2442                         throw new NotImplementedException ();
2443                 }
2444
2445         [MonoTODO]
2446         public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback callback, object state)
2447         {
2448             throw new NotImplementedException();
2449         }
2450
2451                 [MonoNotSupported ("")]
2452                 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback callback, object state)
2453                 {
2454                         throw new NotImplementedException ();
2455                 }
2456
2457                 [MonoNotSupported ("")]
2458                 [CLSCompliantAttribute (false)]
2459                 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, 
2460                                                                                 out SocketError errorCode, AsyncCallback callback, 
2461                                                                                 object state)
2462                 {
2463                         throw new NotImplementedException ();
2464                 }
2465
2466         [MonoTODO]
2467         public IAsyncResult BeginSend(byte[] buffer, int offset, int size,
2468                                         SocketFlags socketFlags, out SocketError errorCode,
2469                                         AsyncCallback callback, object state)
2470         {
2471             throw new NotImplementedException();
2472         }
2473
2474                 [MonoNotSupported ("")]
2475                 public int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
2476                 {
2477                         throw new NotImplementedException ();
2478                 }
2479
2480                 [MonoNotSupported ("")]
2481                 public IAsyncResult BeginReceive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, Object state)
2482                 {
2483                         throw new NotImplementedException ();
2484                 }
2485
2486                 [CLSCompliantAttribute (false)]
2487                 [MonoNotSupported ("")]
2488                 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback callback, Object state)
2489                 {
2490                         throw new NotImplementedException ();
2491                 }
2492
2493                 [CLSCompliantAttribute (false)]
2494                 [MonoNotSupported ("")]
2495                 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, Object state)
2496                 {
2497                         throw new NotImplementedException ();
2498                 }
2499
2500                 [MonoNotSupported ("")]
2501                 public int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
2502                 {
2503                         throw new NotImplementedException ();
2504                 }
2505
2506                 [MonoNotSupported ("")]
2507                 public void SendFile (string fileName)
2508                 {
2509                         throw new NotImplementedException ();
2510                 }
2511
2512                 [MonoNotSupported ("")]
2513                 public void SendFile (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags)
2514                 {
2515                         throw new NotImplementedException ();
2516                 }
2517
2518                 [MonoNotSupported ("")]
2519                 public IAsyncResult BeginSendFile (string fileName, AsyncCallback callback, object state)
2520                 {
2521                         throw new NotImplementedException ();
2522                 }
2523
2524                 [MonoNotSupported ("")]
2525                 public IAsyncResult BeginSendFile (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags, AsyncCallback callback, object state)
2526                 {
2527                         throw new NotImplementedException ();
2528                 }
2529
2530                 [MonoNotSupported ("")]
2531                 public void EndSendFile (IAsyncResult asyncResult)
2532                 {
2533                         throw new NotImplementedException ();
2534                 }
2535
2536         [MonoTODO]
2537         public void Close(int timeout)
2538         {
2539             throw new NotImplementedException();
2540         }
2541
2542         [MonoTODO]
2543         public void Connect(IPAddress address, int port)
2544         {
2545             throw new NotImplementedException();
2546         }
2547
2548         [MonoTODO]
2549         public void Connect(IPAddress[] address, int port)
2550         {
2551             throw new NotImplementedException();
2552         }
2553
2554         [MonoTODO]
2555         public void Connect(string host, int port)
2556         {
2557             throw new NotImplementedException();
2558         }
2559
2560                 [MonoNotSupported ("")]
2561                 public void Disconnect (bool reuseSocket)
2562                 {
2563                         throw new NotImplementedException ();
2564                 }
2565
2566                 [MonoNotSupported ("")]
2567                 public SocketInformation DuplicateAndClose (int targetProcessId)
2568                 {
2569                         throw new NotImplementedException ();
2570                 }
2571                         #endregion //Methods
2572
2573         #endregion
2574
2575         void IDisposable.Dispose ()
2576                 {
2577                         Dispose (true);
2578                         GC.SuppressFinalize (this);
2579                 }
2580                 
2581                 ~Socket () {
2582                         Dispose(false);
2583                 }
2584
2585         }
2586 }