diff options
author | Jerome Laban <jerome@mono-cvs.ximian.com> | 2003-07-14 20:03:20 +0400 |
---|---|---|
committer | Jerome Laban <jerome@mono-cvs.ximian.com> | 2003-07-14 20:03:20 +0400 |
commit | 3d171d4a851f48063699115b5b4c4ae29f2f42bf (patch) | |
tree | 913a6644283361e537538ba8dbdaece346ad3377 /mcs/class/System/System.Net.Sockets | |
parent | 32ab64c0936f1ff98155c93a17365e04c826467f (diff) |
2003-07-14 Jerome Laban <jlaban@wanadoo.fr>
* Socket.cs:
* ProtocolType.cs:
* SocketOptionLevel.cs:
* TcpListener.cs:
* TcpClient.cs:
* UdpClient.cs:
Added IPv6 support.
* IPv6MulticastOption.cs: Added for IPv6 support.
svn path=/trunk/mcs/; revision=16217
Diffstat (limited to 'mcs/class/System/System.Net.Sockets')
-rw-r--r-- | mcs/class/System/System.Net.Sockets/ChangeLog | 13 | ||||
-rwxr-xr-x | mcs/class/System/System.Net.Sockets/IPv6MulticastOption.cs | 54 | ||||
-rw-r--r-- | mcs/class/System/System.Net.Sockets/ProtocolType.cs | 6 | ||||
-rw-r--r-- | mcs/class/System/System.Net.Sockets/Socket.cs | 76 | ||||
-rw-r--r-- | mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs | 6 | ||||
-rwxr-xr-x | mcs/class/System/System.Net.Sockets/TcpClient.cs | 48 | ||||
-rwxr-xr-x | mcs/class/System/System.Net.Sockets/TcpListener.cs | 11 | ||||
-rw-r--r-- | mcs/class/System/System.Net.Sockets/UdpClient.cs | 83 |
8 files changed, 267 insertions, 30 deletions
diff --git a/mcs/class/System/System.Net.Sockets/ChangeLog b/mcs/class/System/System.Net.Sockets/ChangeLog index f1167857c0c..8f40822eceb 100644 --- a/mcs/class/System/System.Net.Sockets/ChangeLog +++ b/mcs/class/System/System.Net.Sockets/ChangeLog @@ -1,3 +1,16 @@ +2003-07-14 Jerome Laban <jlaban@wanadoo.fr> + + * Socket.cs: + * ProtocolType.cs: + * SocketOptionLevel.cs: + * TcpListener.cs: + * TcpClient.cs: + * UdpClient.cs: + + Added IPv6 support. + + * IPv6MulticastOption.cs: Added for IPv6 support. + 2003-05-16 Dick Porter <dick@ximian.com> * Socket.cs: Use Mono.Posix.UnixEndPoint if its available diff --git a/mcs/class/System/System.Net.Sockets/IPv6MulticastOption.cs b/mcs/class/System/System.Net.Sockets/IPv6MulticastOption.cs new file mode 100755 index 00000000000..4cc2090e090 --- /dev/null +++ b/mcs/class/System/System.Net.Sockets/IPv6MulticastOption.cs @@ -0,0 +1,54 @@ +// +// System.Net.Sockets.MulticastOption.cs +// +// Author: +// Andrew Sutton +// +// (C) Andrew Sutton +// + +using System; +using System.Net; + +namespace System.Net.Sockets +{ +#if NET_1_1 + // <remarks> + // Encapsulates a multicast option + // </remarks> + public class IPv6MulticastOption + { + // Don't change the names of these fields without also + // changing socket-io.c in the runtime + private IPAddress group; + private long ifIndex; + + public IPv6MulticastOption (IPAddress group) + : this (group, 0) + { + + } + + public IPv6MulticastOption (IPAddress group, long ifIndex) + { + if (group == null) + throw new ArgumentNullException ("grp"); + + this.group = group; + this.ifIndex = ifIndex; + } + + public IPAddress Group + { + get { return group; } + set { group = value; } + } + + public long InterfaceIndex + { + get { return ifIndex; } + set { ifIndex = value; } + } + } +#endif +} diff --git a/mcs/class/System/System.Net.Sockets/ProtocolType.cs b/mcs/class/System/System.Net.Sockets/ProtocolType.cs index 0b106e5f946..36a204460f1 100644 --- a/mcs/class/System/System.Net.Sockets/ProtocolType.cs +++ b/mcs/class/System/System.Net.Sockets/ProtocolType.cs @@ -49,6 +49,12 @@ namespace System.Net.Sockets { /// </summary> Idp = 22, +#if NET_1_1 + /// <summary> + /// </summary> + IPv6 = 41, +#endif + /// <summary> /// </summary> ND = 77, diff --git a/mcs/class/System/System.Net.Sockets/Socket.cs b/mcs/class/System/System.Net.Sockets/Socket.cs index 9e370cf5e52..b40658ecc7b 100644 --- a/mcs/class/System/System.Net.Sockets/Socket.cs +++ b/mcs/class/System/System.Net.Sockets/Socket.cs @@ -258,6 +258,12 @@ namespace System.Net.Sockets private SocketType socket_type; private ProtocolType protocol_type; private bool blocking=true; +
+ /*
+ * These two fields are looked up by name by the runtime, don't change
+ * their name without also updating the runtime code.
+ */ + private static int ipv4Supported = -1, ipv6Supported = -1; /* When true, the socket was connected at the time of * the last IO operation @@ -463,7 +469,7 @@ namespace System.Net.Sockets sa=LocalEndPoint_internal(socket); - if(sa.Family==AddressFamily.InterNetwork) { + if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6) { // Stupidly, EndPoint.Create() is an // instance method return new IPEndPoint(0, 0).Create(sa); @@ -493,7 +499,7 @@ namespace System.Net.Sockets sa=RemoteEndPoint_internal(socket); - if(sa.Family==AddressFamily.InterNetwork) { + if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6 ) { // Stupidly, EndPoint.Create() is an // instance method return new IPEndPoint(0, 0).Create(sa); @@ -512,6 +518,70 @@ namespace System.Net.Sockets } } +#if NET_1_1 + public static bool SupportsIPv4 {
+ get {
+ CheckProtocolSupport();
+ return ipv4Supported == 1;
+ }
+ } + + public static bool SupportsIPv6 {
+ get {
+ CheckProtocolSupport();
+ return ipv6Supported == 1;
+ }
+ } +#else + internal static bool SupportsIPv4
+ {
+ get
+ {
+ return true;
+ }
+ } + + internal static bool SupportsIPv6
+ {
+ get
+ {
+ return false;
+ }
+ }
+#endif + + internal static void CheckProtocolSupport() + {
+ if(ipv4Supported == -1) {
+ try {
+ Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ tmp.Close();
+
+ ipv4Supported = 1;
+ }
+ catch {
+ ipv4Supported = 0;
+ }
+ }
+
+ if(ipv6Supported == -1) {
+ NetConfig config = (NetConfig)System.Configuration.ConfigurationSettings.GetConfig("system.net/settings");
+
+ if(config != null)
+ ipv6Supported = config.ipv6Enabled?-1:0;
+
+ if(ipv6Supported != 0) {
+ try {
+ Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+ tmp.Close();
+
+ ipv6Supported = 1;
+ }
+ catch { }
+ }
+ }
+ } + // Creates a new system socket, returning the handle [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern static IntPtr Accept_internal(IntPtr sock); @@ -635,7 +705,7 @@ namespace System.Net.Sockets if(remote_end==null) { throw new ArgumentNullException(); } - + Connect_internal(socket, remote_end.Serialize()); connected=true; } diff --git a/mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs b/mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs index 657a4532154..dd3a69c0749 100644 --- a/mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs +++ b/mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs @@ -25,6 +25,12 @@ namespace System.Net.Sockets { /// </summary> IP = 0, +#if NET_1_1 + /// <summary> + /// </summary> + IPv6 = 41, +#endif + /// <summary> /// </summary> Tcp = 6, diff --git a/mcs/class/System/System.Net.Sockets/TcpClient.cs b/mcs/class/System/System.Net.Sockets/TcpClient.cs index 1ef74a648fc..c2efc35a456 100755 --- a/mcs/class/System/System.Net.Sockets/TcpClient.cs +++ b/mcs/class/System/System.Net.Sockets/TcpClient.cs @@ -32,11 +32,16 @@ namespace System.Net.Sockets /// <summary> /// Some code that is shared between the constructors. /// </summary> - private void Init () + private void Init (AddressFamily family) { active = false; - client = new Socket(AddressFamily.InterNetwork, - SocketType.Stream, ProtocolType.Tcp); + + if(client != null) {
+ client.Close();
+ client = null;
+ } + + client = new Socket(family, SocketType.Stream, ProtocolType.Tcp); } /// <summary> @@ -44,7 +49,7 @@ namespace System.Net.Sockets /// </summary> public TcpClient () { - Init(); + Init(AddressFamily.InterNetwork); client.Bind(new IPEndPoint(IPAddress.Any, 0)); } @@ -57,7 +62,7 @@ namespace System.Net.Sockets /// <param name="local_end_point">The aforementioned local endpoint</param> public TcpClient (IPEndPoint local_end_point) { - Init(); + Init(local_end_point.AddressFamily); client.Bind(local_end_point); } @@ -71,8 +76,6 @@ namespace System.Net.Sockets /// <param name="port">The port to connect to, e.g. 80 for HTTP</param> public TcpClient (string hostname, int port) { - Init(); - client.Bind(new IPEndPoint(IPAddress.Any, 0)); Connect(hostname, port); } @@ -276,10 +279,35 @@ namespace System.Net.Sockets public void Connect (string hostname, int port) { CheckDisposed (); + IPHostEntry host = Dns.GetHostByName(hostname); - /* TODO: This will connect to the first IP address returned - from GetHostByName. Is that right? */ - Connect(new IPEndPoint(host.AddressList[0], port)); + + for(int i=0; i<host.AddressList.Length; i++) + {
+ try {
+ Init(host.AddressList[i].AddressFamily); + + if(host.AddressList[i].AddressFamily == AddressFamily.InterNetwork) + client.Bind(new IPEndPoint(IPAddress.Any, 0)); +#if NET_1_1 + else if(host.AddressList[i].AddressFamily == AddressFamily.InterNetworkV6) + client.Bind(new IPEndPoint(IPAddress.IPv6Any, 0)); +#endif + + Connect(new IPEndPoint(host.AddressList[i], port)); + break; + }
+ catch(Exception e) {
+ if(client != null) {
+ client.Close();
+ client = null;
+ }
+
+ /// This is the last known address, re-throw the exception
+ if(i == host.AddressList.Length-1)
+ throw e;
+ }
+ } } /// <summary> diff --git a/mcs/class/System/System.Net.Sockets/TcpListener.cs b/mcs/class/System/System.Net.Sockets/TcpListener.cs index feedae68b90..0a6e598b314 100755 --- a/mcs/class/System/System.Net.Sockets/TcpListener.cs +++ b/mcs/class/System/System.Net.Sockets/TcpListener.cs @@ -30,11 +30,10 @@ namespace System.Net.Sockets /// <summary> /// Some code that is shared between the constructors. /// </summary> - private void Init () + private void Init (AddressFamily family) { active = false; - server = new Socket(AddressFamily.InterNetwork, - SocketType.Stream, ProtocolType.Tcp); + server = new Socket(family, SocketType.Stream, ProtocolType.Tcp); } /// <summary> @@ -44,7 +43,7 @@ namespace System.Net.Sockets /// are a web server</param> public TcpListener (int port) { - Init(); + Init(AddressFamily.InterNetwork); server.Bind(new IPEndPoint(IPAddress.Any, port)); } @@ -54,7 +53,7 @@ namespace System.Net.Sockets /// <param name="local_end_point">The endpoint</param> public TcpListener (IPEndPoint local_end_point) { - Init(); + Init(local_end_point.AddressFamily); server.Bind(local_end_point); } @@ -66,7 +65,7 @@ namespace System.Net.Sockets /// <param name="port">The port to listen on</param> public TcpListener (IPAddress listen_ip, int port) { - Init(); + Init(listen_ip.AddressFamily); server.Bind(new IPEndPoint(listen_ip, port)); } diff --git a/mcs/class/System/System.Net.Sockets/UdpClient.cs b/mcs/class/System/System.Net.Sockets/UdpClient.cs index 3a2b85a833b..77d50299116 100644 --- a/mcs/class/System/System.Net.Sockets/UdpClient.cs +++ b/mcs/class/System/System.Net.Sockets/UdpClient.cs @@ -17,10 +17,19 @@ namespace System.Net.Sockets private bool disposed = false;
private bool active = false;
private Socket socket;
+ private AddressFamily family = AddressFamily.InterNetwork;
#region Constructors
- public UdpClient ()
+ public UdpClient () : this(AddressFamily.InterNetwork)
{
+ }
+
+ public UdpClient(AddressFamily family)
+ {
+ if(family != AddressFamily.InterNetwork && family != AddressFamily.InterNetwork)
+ throw new ArgumentException("family");
+
+ this.family = family;
InitSocket (null);
}
@@ -29,6 +38,8 @@ namespace System.Net.Sockets if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
throw new ArgumentOutOfRangeException ("port");
+ this.family = AddressFamily.InterNetwork;
+
IPEndPoint localEP = new IPEndPoint (IPAddress.Any, port);
InitSocket (localEP);
}
@@ -38,6 +49,8 @@ namespace System.Net.Sockets if (localEP == null)
throw new ArgumentNullException ("localEP");
+ this.family = localEP.AddressFamily;
+
InitSocket (localEP);
}
@@ -55,7 +68,13 @@ namespace System.Net.Sockets private void InitSocket (EndPoint localEP)
{
- socket = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ if(socket != null) {
+ socket.Close();
+ socket = null;
+ }
+
+ socket = new Socket (family, SocketType.Dgram, ProtocolType.Udp);
+
if (localEP != null)
socket.Bind (localEP);
}
@@ -95,25 +114,61 @@ namespace System.Net.Sockets if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
throw new ArgumentOutOfRangeException ("port");
- Connect (new IPEndPoint (Dns.Resolve (hostname).AddressList [0], port));
+ IPAddress[] addresses = Dns.Resolve (hostname).AddressList;
+ for(int i=0; i<addresses.Length; i++) {
+ try {
+ Console.WriteLine("Trying: {0}, Family: {1}", addresses[i], addresses[i].AddressFamily);
+
+ this.family = addresses[i].AddressFamily;
+ Connect (new IPEndPoint (addresses[i], port));
+
+ Console.WriteLine("Connected: {0}, Family: {1}", addresses[i], family);
+ break;
+ }
+ catch(Exception e) {
+ if(i == addresses.Length - 1){
+ if(socket != null) {
+ socket.Close();
+ socket = null;
+ }
+
+ /// This is the last entry, re-throw the exception
+ throw e;
+ }
+ }
+ }
+
}
#endregion
-#region Multicast methods
+ #region Multicast methods
public void DropMulticastGroup (IPAddress multicastAddr)
{
CheckDisposed ();
if (multicastAddr == null)
throw new ArgumentNullException ("multicastAddr");
- socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DropMembership,
- new MulticastOption (multicastAddr));
+ if(family == AddressFamily.InterNetwork)
+ socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DropMembership,
+ new MulticastOption (multicastAddr));
+#if NET_1_1
+ else
+ socket.SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DropMembership,
+ new IPv6MulticastOption (multicastAddr));
+#endif
}
public void JoinMulticastGroup (IPAddress multicastAddr)
{
CheckDisposed ();
- socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership,
- new MulticastOption (multicastAddr));
+
+ if(family == AddressFamily.InterNetwork)
+ socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership,
+ new MulticastOption (multicastAddr));
+#if NET_1_1
+ else
+ socket.SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.AddMembership,
+ new IPv6MulticastOption (multicastAddr));
+#endif
}
public void JoinMulticastGroup (IPAddress multicastAddr, int timeToLive)
@@ -123,10 +178,16 @@ namespace System.Net.Sockets if (timeToLive < 0 || timeToLive > 255)
throw new ArgumentOutOfRangeException ("timeToLive");
- socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive,
- timeToLive);
+ if(family == AddressFamily.InterNetwork)
+ socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive,
+ timeToLive);
+#if NET_1_1
+ else
+ socket.SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive,
+ timeToLive);
+#endif
}
-#endregion
+ #endregion
#region Data I/O
public byte [] Receive (ref IPEndPoint remoteEP)
{
|