[Mono-bugs] [Bug 35371][Nor] Changed - Setting ReceiveTimeout causes exception

bugzilla-daemon@rocky.ximian.com bugzilla-daemon@rocky.ximian.com
Sat, 31 May 2003 15:08:45 -0400 (EDT)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by groith@tcrz.net.

http://bugzilla.ximian.com/show_bug.cgi?id=35371

--- shadow/35371	Sat May 31 07:18:32 2003
+++ shadow/35371.tmp.5025	Sat May 31 15:08:45 2003
@@ -112,6 +112,185 @@
 
          {
 
           Console.WriteLine ("Request timed out.");
 
          }
+
+------- Additional Comments From groith@tcrz.net  2003-05-31 15:08 -------
+Here is a complete testcase, though it's a bit long:
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Ping
+{
+
+  class Ping
+  {
+    const int SOCKET_ERROR = -1;
+    const int ICMP_ECHO = 8;
+
+    public static void Main(string[] args)
+    {
+	PingHost("192.168.10.1", 32, 4, 1000);
+    }
+
+    public static void PingHost(string strPingHost, int iPingBytes, 
+uint lngPingCount, uint lngPingTimeout)
+    {
+      const int     MAX_PACKET_SIZE = 65535;
+      IPHostEntry   PingTarget, PingSource;
+      int           iBytesReceived = 0;
+      int           dwStart = 0, dwStop = 0;
+      uint          iLoop = 0;
+      bool          bContinuous = false;
+
+      PingTarget = Dns.GetHostByName(strPingHost);
+
+      IPEndPoint ipepServer = new IPEndPoint(PingTarget.AddressList
+[0],0);
+      EndPoint epServer = (ipepServer);
+
+      PingSource = Dns.GetHostByName(Dns.GetHostName());
+      IPEndPoint ipEndPointFrom = new IPEndPoint
+(PingSource.AddressList[0],0);
+      EndPoint   EndPointFrom = (ipEndPointFrom);
+
+      int iPacketSize = 0;
+      IcmpPacket PingPacket = new IcmpPacket();
+      PingPacket.Type = ICMP_ECHO; //8
+      PingPacket.SubCode = 0;
+      PingPacket.CheckSum = UInt16.Parse("0");
+      PingPacket.Identifier   = UInt16.Parse("45");
+      PingPacket.SequenceNumber  = UInt16.Parse("0");
+      PingPacket.Data = new Byte[iPingBytes];
+
+      for (int iCount = 0; iCount < iPingBytes; iCount++)
+      {
+        PingPacket.Data[iCount] = (byte)'#';
+      }
+
+      iPacketSize = iPingBytes + 8;
+      byte [] bytPktBuffer = new byte[iPacketSize];
+      int iResult = 0;
+
+      ushort [] cksum_buffer = new ushort[Convert.ToInt32( 
+Math.Ceiling( Convert.ToDouble(iResult) / 2))];
+      
+      int icmp_header_buffer_index = 0;
+      for( int iCount = 0; iCount < cksum_buffer.Length; iCount++ ) 
+      {
+        cksum_buffer[iCount] = BitConverter.ToUInt16(bytPktBuffer, 
+icmp_header_buffer_index);
+        icmp_header_buffer_index += 2;
+      }
+
+      byte [] byteSendBuffer = new byte[ iPacketSize ];
+
+      if (lngPingCount == 0) bContinuous = true;
+
+      long lngPacketsSent = 0, lngPacketsReceived = 0, 
+lngTotalTransmitTime = 0;
+      int  iMinTransmitTime = int.MaxValue, iMaxTransmitTime = 
+int.MinValue;
+      do 
+      {
+        bool bReceived = false ;
+
+        Socket PingSocket = new Socket(AddressFamily.InterNetwork, 
+SocketType.Raw, ProtocolType.Icmp);
+
+	// Mono Bug 1:
+	// This should work without catching the exception
+
+	try {
+        PingSocket.SetSocketOption( SocketOptionLevel.Socket, 
+SocketOptionName.ReceiveTimeout, (int) lngPingTimeout);
+        PingSocket.SetSocketOption( SocketOptionLevel.Socket, 
+SocketOptionName.SendTimeout, (int) lngPingTimeout);
+	}
+	catch {}
+        
+        byte [] ReceiveBuffer = new byte [MAX_PACKET_SIZE];
+
+        dwStart = System.Environment.TickCount; // Start timing
+        lngPacketsSent ++;
+        iResult = PingSocket.SendTo(byteSendBuffer, iPacketSize, 
+SocketFlags.None , epServer);
+        iBytesReceived = 0;
+        while(!bReceived)
+        {
+          try 
+          {
+            // Mono Bug 2:
+            // On Linux This will just hang, instead of going on.
+
+            iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer, 
+MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);
+          }
+          catch //(Exception e)
+          {
+            Console.WriteLine ("Request timed out.");
+            bReceived = false;
+            break;
+          }
+          if (iBytesReceived == SOCKET_ERROR)
+          {
+            Console.WriteLine("Host not Responding") ;
+            bReceived = false;
+            break;
+
+          } 
+          else if (iBytesReceived > 0) 
+          {
+            bReceived = true;
+            dwStop = System.Environment.TickCount - dwStart; // stop 
+timing
+
+            //Check for timeout
+            if ( dwStop > lngPingTimeout)
+            {
+              Console.WriteLine ("Request timed out.");
+              bReceived = false;
+              System.Threading.Thread.Sleep
+(System.TimeSpan.FromMilliseconds(1000));
+              break;
+            }
+            break;
+          } 
+        }
+
+
+        iLoop++;
+
+        if (bReceived & 
+          (bContinuous | (iLoop < lngPingCount)))
+        { 
+          System.Threading.Thread.Sleep
+(System.TimeSpan.FromMilliseconds(1000));
+        }
+
+        PingSocket.Shutdown(SocketShutdown.Both);
+        PingSocket.Close();
+      } while (bContinuous | (iLoop < lngPingCount));
+
+    }
+
+
+    public class IcmpPacket
+    {
+      public byte     Type;             // type of message
+      public byte     SubCode;          // type of sub code
+      public ushort   CheckSum;         // ones complement checksum 
+of struct
+      public ushort   Identifier;       // identifier
+      public ushort   SequenceNumber;   // sequence number  
+      public byte[]   Data;             // byte array of data
+    }
+  }
+}
+
+
+
+