GHStreamSocket.jvm.cs :  » 2.6.4-mono-.net-core » System.Net » System » Net » Sockets » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Net 
System.Net » System » Net » Sockets » GHStreamSocket.jvm.cs
using java.nio.channels;
using java.security;
using javax.net.ssl;

namespace System.Net.Sockets{
  /// <summary>
  /// Summary description for GHStreamSocket.
  /// </summary>
  internal class GHStreamSocket : GHSocket
  {
    java.net.ServerSocket jServerSocket;
    java.net.Socket jSocket;
    java.nio.channels.ServerSocketChannel jServerSocketChannel;
    java.nio.channels.SocketChannel jSocketChannel;

    // This field I need because a bug in the java.nio.channels.SocketAdapter, which 
    // returns local port 0 if the socket is not connected (even if the socket is bound)
    // so I need temporary use regular socket (not channel socket) to bind it to the 
    // local address and use this address in the LocalPoint property and to create the 
    // actual client/server channel sockets
    // The bug #5076965 (SocketChannel does not report local address after binding to a wildcard )
    // See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5076965
    java.net.InetSocketAddress jTempLocalSocketAddress;

    public GHStreamSocket()
    {
      jSocketChannel = java.nio.channels.SocketChannel.open();
      jSocket = jSocketChannel.socket();
    }

    public GHStreamSocket(java.nio.channels.SocketChannel socketChannel)
    {
      jSocketChannel = socketChannel;
      jSocket = jSocketChannel.socket();
    }

    public override int GetHashCode ()
    {
      if (jSocket == null && jServerSocket == null)
        return -1;

      if (jServerSocket != null) {
        return jServerSocket.ToString ().GetHashCode ();
      }

      return jSocket.ToString ().GetHashCode ();
    }

    public int Available_internal(out int error)
    {
      error = 0;
      int r = 0;

      if (jSocket == null || !jSocket.isConnected())
      {
        return r;
      }

      try
      {
        r = jSocket.getInputStream().available();
      }
      catch (Exception e)
      {
        error = 10054; //WSAECONNRESET (Connection reset by peer)
        r = 0;
#if DEBUG
        Console.WriteLine("Caught exception during Available_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      return r;
    }

    public void Blocking_internal(bool block, out int error)
    {
      error = 0;

      if (jSocket == null && jServerSocket == null)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        return;
      }

      try
      {
        if (jServerSocket != null)
        {
          jServerSocketChannel.configureBlocking(block);
        }
        else
        {
          jSocketChannel.configureBlocking(block);
        }
      }
      catch (Exception e)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
        Console.WriteLine("Caught exception during Blocking_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }
    }

    public EndPoint LocalEndPoint_internal(out int error)
    {
      error = 0;
      java.net.InetSocketAddress localAddr = null;

      try
      {
        if (jTempLocalSocketAddress != null)
        {
          localAddr = jTempLocalSocketAddress;
        }
        else if (jServerSocket != null)
        {
          localAddr = (java.net.InetSocketAddress)jServerSocket.getLocalSocketAddress();
        }
        else
        {
          localAddr = (java.net.InetSocketAddress)jSocket.getLocalSocketAddress();
        }
      }
      catch (Exception e)
      {
        localAddr = null;
#if DEBUG
        Console.WriteLine("Caught exception during LocalEndPoint_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      if (localAddr == null || localAddr.getAddress() == null || localAddr.getPort() < 0)
      {
                return null;
      }

      IPHostEntry lipa = Dns.Resolve(localAddr.getHostName());
      IPEndPoint ret = new IPEndPoint(lipa.AddressList[0], localAddr.getPort());
      return ret;
    }

    public EndPoint RemoteEndPoint_internal(out int error)
    {
      error = 0;
      java.net.InetSocketAddress remoteAddr = null;

      if (jSocket == null || !jSocket.isBound())
      {
        return null;
      }

      try
      {
        remoteAddr = (java.net.InetSocketAddress)jSocket.getRemoteSocketAddress();
      }
      catch (Exception e)
      {
        remoteAddr = null;
#if DEBUG
        Console.WriteLine("Caught exception during RemoteEndPoint_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      if (remoteAddr == null || remoteAddr.getAddress() == null || remoteAddr.getPort() <= 0)
      {
        error = 10057; //WSAENOTCONN (Socket is not connected)
        return null;
      }

      IPHostEntry lipa = Dns.Resolve(remoteAddr.getHostName());
      IPEndPoint ret = new IPEndPoint(lipa.AddressList[0], remoteAddr.getPort());
      return ret;
    }

    public GHSocket Accept_internal(out int error)
    {
      error = 0;

      if (jServerSocket == null)
      {
        throw new InvalidOperationException("You must call Bind and Listen before calling Accept.");
      }

      try
      {
        /*
          If this channel is in non-blocking mode then this method will immediately 
          return null if there are no pending connections. 
          Otherwise it will block indefinitely until a new connection is 
          available or an I/O error occurs.         
        */
        java.nio.channels.SocketChannel acceptedSocket = jServerSocketChannel.accept();
        if (acceptedSocket == null) 
        {
          error = 10035; //WSAEWOULDBLOCK (Resource temporarily unavailable)
#if DEBUG
          Console.WriteLine("The Accept_internal is in non-blocking mode and no pending connections are available");
#endif
          return null;
        }

        return new GHStreamSocket(acceptedSocket);
      }
      catch (AsynchronousCloseException) {
        error = 10004;
      }
      catch (Exception e)
      {
        error = 10061; //WSAECONNREFUSED (Connection refused)
#if DEBUG
        Console.WriteLine("Caught exception during Accept_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      return null;
    }

    public void Bind_internal(EndPoint sa, out int error)
    {
      error = 0;
      IPEndPoint addr = sa as IPEndPoint;
      if (addr == null)
      {
        error = 10044; //WSAESOCKTNOSUPPORT (Socket type not supported)
        return;
      }

      if (jSocket == null || jSocket.isBound() || jSocket.isConnected() || jSocketChannel.isConnectionPending())
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        return;
      }

      try
      {
        // This code I need because a bug in the java.nio.channels.SocketAdapter, which 
        // returns local port 0 if the socket is not connected (even if the socket is bound)
        // so I need temporary use regular socket (not channel socket) to bind it to the 
        // local address and use this address in the LocalPoint property and to create the 
        // actual client/server channel sockets
        // The bug #5076965 (SocketChannel does not report local address after binding to a wildcard )
        // See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5076965
        java.net.Socket jTempSocket = new java.net.Socket();
        jTempSocket.bind(new java.net.InetSocketAddress(java.net.InetAddress.getByName(addr.Address.ToString()),
                                          addr.Port));
        jTempLocalSocketAddress = (java.net.InetSocketAddress)jTempSocket.getLocalSocketAddress();
        jTempSocket.close();
        jSocket.bind(jTempLocalSocketAddress);
      }
      catch (Exception e)
      {
        error = 10048; //WSAEADDRINUSE (Address already in use)
#if DEBUG
        Console.WriteLine("Caught exception during Bind_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }
    }

    public void Close_internal(out int error)
    {
      error = 0;

      if (jServerSocket != null)
      {
        try
        {
          jServerSocket.close();
        }
        catch (Exception e)
        {
          error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
          Console.WriteLine("Caught exception during Close_internal jServerSocket - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
        }
        try
        {
          jServerSocketChannel.close();
        }
        catch (Exception e)
        {
          error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
          Console.WriteLine("Caught exception during Close_internal jServerSocketChannel - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
        }
        jServerSocket = null;
        jServerSocketChannel = null;
      }
      else if (jSocket != null)
      {
        try
        {
          jSocket.close();
        }
        catch (Exception e)
        {
          error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
          Console.WriteLine("Caught exception during Close_internal jSocket - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
        }
        try
        {
          jSocketChannel.close();
        }
        catch (Exception e)
        {
          error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
          Console.WriteLine("Caught exception during Close_internal jSocketChannel - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
        }
        jSocket = null;
        jSocketChannel = null;
      }
    }

    public void Connect_internal(EndPoint sa, out int error)
    {
      error = 0;

      IPEndPoint addr = sa as IPEndPoint;
      if (addr == null)
      {
        error = 10044; //WSAESOCKTNOSUPPORT (Socket type not supported)
        return;
      }

      if (jSocket == null)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        return;
      }

      if (jSocket.isConnected() || jSocketChannel.isConnectionPending())
      {
        error = 10056; //WSAEISCONN (Socket is already connected)
        return;
      }

      try
      {
        /*
         If this channel is in non-blocking mode then an invocation of this method
         initiates a non-blocking connection operation. If the connection is 
         established immediately, as can happen with a local connection, then this 
         method returns true. Otherwise this method returns false.  
                 If this channel is in blocking mode then an invocation of this method 
         will block until the connection is established or an I/O error occurs. 
         */
        bool status = jSocketChannel.connect(new java.net.InetSocketAddress(
          java.net.InetAddress.getByName(addr.Address.ToString()), 
          addr.Port));
        if (!status)
        {
          error = 10035; //WSAEWOULDBLOCK (Resource temporarily unavailable)
        }
      }
      catch (java.nio.channels.AlreadyConnectedException ae)
      {        
        error = 10056; //WSAEISCONN (Socket is already connected)
      }
      catch (java.nio.channels.ConnectionPendingException cpe)
      {        
        error = 10036; //WSAEINPROGRESS (Operation now in progress)
      }
      catch (java.nio.channels.UnresolvedAddressException uae)
      {        
        error = 10039; //WSAEDESTADDRREQ (Destination address required)
      }
      catch (java.nio.channels.UnsupportedAddressTypeException uate)
      {        
        error = 10041; //WSAEPROTOTYPE (Protocol wrong type for socket)
      }
      catch (AsynchronousCloseException) {
        error = 10004;
      }
      catch (Exception e)
      {        
        error = 10061; //WSAECONNREFUSED (Connection refused)
#if DEBUG
        Console.WriteLine("Caught exception during Connect_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }
    }

    public void Listen_internal(int backlog, out int error)
    {
      error = 0;

      if (jSocket == null || !jSocket.isBound())
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        return;
      }

      if (jSocket.isConnected() || jSocketChannel.isConnectionPending())
      {
        error = 10056; //WSAEISCONN (Socket is already connected)
        return;
      }

      bool blockMode = jSocketChannel.isBlocking();
      bool reuseAddr = jSocket.getReuseAddress();

      try
      {
        jSocket.close();
      }
      catch (Exception e)
      {
#if DEBUG
        Console.WriteLine("Caught exception during Listen_internal close old jSocket - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      try
      {
        jSocketChannel.close();
      }
      catch (Exception e)
      {
#if DEBUG
        Console.WriteLine("Caught exception during Listen_internal close old jSocketChannel - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      jSocket = null;
      jSocketChannel = null;

      try
      {
        jServerSocketChannel = java.nio.channels.ServerSocketChannel.open();
        jServerSocket = jServerSocketChannel.socket();
        jServerSocket.bind(jTempLocalSocketAddress, backlog);
        jServerSocketChannel.configureBlocking(blockMode);
        jServerSocket.setReuseAddress(reuseAddr);
      }
      catch (Exception e)
      {
        error = 10048; //WSAEADDRINUSE (Address already in use)
#if DEBUG
        Console.WriteLine("Caught exception during Listen_internal create server socket - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }
    }

    public bool Poll_internal (SelectMode mode, int timeout, Socket source, out int error)
    {
      error = 0;

      if (mode == SelectMode.SelectError && !jSocketChannel.isConnectionPending())
      {
        return false;
      }

      java.nio.channels.Selector selector = java.nio.channels.Selector.open();
      RegisterSelector(selector, ((mode == SelectMode.SelectRead)?0:1), source, out error);

      if (error != 0)
      {
        error = 0;
        GHSocketFactory.CloseSelector(selector);
        return (mode == SelectMode.SelectError);
      }

      bool retVal = false;

      long timeOutMillis = 1;
      if (timeout < 0)
      {
        timeOutMillis = 0;
      } 
      else if (timeout > 999)
      {
        timeOutMillis = (long)(timeout / 1000);
      }

      int readyCount = 0;
      try
      {
        readyCount = selector.select(timeOutMillis);
      }
      catch (Exception e)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
        Console.WriteLine("Caught exception during Poll_internal selector.select - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      if (readyCount > 0)
      {
        if (jSocket != null && jSocketChannel.isConnectionPending())
        {
          bool status = false;
          try
          {
            status = jSocketChannel.finishConnect();
          }
          catch (Exception e)
          {
#if DEBUG
            Console.WriteLine("Caught exception during Poll_internal, finishConnect - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
          }
          if (status)
          {
            retVal =  (mode != SelectMode.SelectError);
          }
          else 
          {
            retVal =  (mode == SelectMode.SelectError);
          }
        }
        else
        {
          retVal =  true;
        }
      }

      GHSocketFactory.CloseSelector(selector);

      return retVal;
    }

    public void RegisterSelector(java.nio.channels.Selector selector, int mode, Socket source, out int error)
    {
      error = 0;
      if (jServerSocket != null)
      {
        // only accept operation, which included to the read list, is allowed for server sockets
        if (mode != 0)
        {
//          error = 10038; //WSAENOTSOCK (Socket operation on nonsocket)
#if DEBUG
          Console.WriteLine("RegisterSelector, invalid mode {0} for the server socket", mode);
#endif
          return;
        }

        try
        {
          if (jServerSocketChannel.isBlocking())
          {
            /*
              A channel must be placed into non-blocking mode before being registered 
              with a selector, and may not be returned to blocking mode until it has been 
              deregistered. 
            */
            jServerSocketChannel.configureBlocking(false);
          }

          jServerSocketChannel.register(selector, java.nio.channels.SelectionKey.OP_ACCEPT, source);
        }
        catch (Exception e)
        {
          error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
          Console.WriteLine("Caught exception during RegisterSelector, register server socket - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
        }
      }
      else
      {
        try
        {
          int ops = java.nio.channels.SelectionKey.OP_READ;
          if (mode > 0)
          {
            if (jSocketChannel.isConnectionPending())
            {
              ops = java.nio.channels.SelectionKey.OP_CONNECT;
            }
            else
            {
              ops = java.nio.channels.SelectionKey.OP_WRITE;
            }
          }
          
          if (jSocketChannel.isBlocking())
          {
            /*
              A channel must be placed into non-blocking mode before being registered 
              with a selector, and may not be returned to blocking mode until it has been 
              deregistered. 
            */
            jSocketChannel.configureBlocking(false);
          }

          jSocketChannel.register(selector, ops, source);
        }
        catch (Exception e)
        {
          error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
          Console.WriteLine("Caught exception during RegisterSelector, register client socket - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
        }
      }
    }

    public bool CheckConnectionFinished()
    {
      bool status = true;
      if (jSocket != null && jSocketChannel.isConnectionPending())
      {
        try
        {
          status = jSocketChannel.finishConnect();
        }
        catch (Exception e)
        {
          status = false;
#if DEBUG
          Console.WriteLine("Caught exception during Poll_internal, finishConnect - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
        }
      }

      return status;
    }

    public int Receive_internal(byte[] buffer,  int offset,  int count, SocketFlags flags,
      out int error)
    {
      error = 0;
      int ret = 0;

      if (jSocket == null)
      {
        error = 10057; //WSAENOTCONN (Socket is not connected)
        return ret;
      }

      try
      {
        if (jSocketChannel.isConnectionPending())
        {
          bool status = jSocketChannel.finishConnect();
          if (!status)
          {
            error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
            Console.WriteLine("Receive_internal, jSocketChannel.finishConnect return false");
#endif
            return 0;
          }
        }
        else if (!jSocketChannel.isConnected())
        {
          error = 10057; //WSAENOTCONN (Socket is not connected)
          return ret;
        }

        java.nio.ByteBuffer readBuff = java.nio.ByteBuffer.wrap(vmw.common.TypeUtils.ToSByteArray(buffer), offset, count);
        ret = jSocketChannel.read(readBuff);
        if (ret < 0) ret = 0;
      }
      catch (Exception e)
      {
        error = 10054; //WSAECONNRESET (Connection reset by peer)
        ret = 0;
#if DEBUG
        Console.WriteLine("Caught exception during Receive_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      if (ret == 0 && !jSocketChannel.isBlocking())
      {
        error = 10035; //WSAEWOULDBLOCK (Resource temporarily unavailable)
      }
      return ret;
    }

    public int RecvFrom_internal(byte[] buffer, int offset, int count,  SocketFlags flags,
      ref SocketAddress sockaddr, out int error)
    {
      return Receive_internal(buffer, offset, count, flags, out error);
    }

    public int Send_internal(byte[] buf, int offset, int count, SocketFlags flags,
      out int error)
    {
      error = 0;
      int ret = 0;

      if (jSocket == null)
      {
        error = 10057; //WSAENOTCONN (Socket is not connected)
        return ret;
      }

      try
      {
        if (jSocketChannel.isConnectionPending())
        {
          bool status = jSocketChannel.finishConnect();
          if (!status)
          {
            error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
            Console.WriteLine("Send_internal, jSocketChannel.finishConnect return false");
#endif
            return 0;
          }
        }
        else if (!jSocketChannel.isConnected())
        {
          error = 10057; //WSAENOTCONN (Socket is not connected)
          return ret;
        }

        java.nio.ByteBuffer writeBuff = java.nio.ByteBuffer.wrap(vmw.common.TypeUtils.ToSByteArray(buf), offset, count);
        ret = jSocketChannel.write(writeBuff);
        if (ret < 0) ret = 0;
      }
      catch (Exception e)
      {
        error = 10054; //WSAECONNRESET (Connection reset by peer)
        ret = 0;
#if DEBUG
        Console.WriteLine("Caught exception during Send_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }

      if (ret == 0 && !jSocketChannel.isBlocking())
      {
        error = 10035; //WSAEWOULDBLOCK (Resource temporarily unavailable)
      }
      return ret;
    }

    public int SendTo_internal(byte[] buffer, int offset, int count,
      SocketFlags flags,  SocketAddress sa, out int error)
    {
      return Send_internal(buffer, offset, count, flags, out error);
    }

    public void SetSocketOption_internal (SocketOptionLevel level,
      SocketOptionName name, object obj_val,
      byte [] byte_val, int int_val, out int error)
    {
      error = 0;

      if (byte_val != null)
      {
        error = -1;
        throw new NotImplementedException();
      }

      if (jSocket == null && jServerSocket == null)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        return;
      }

      switch (level)
      {
        case SocketOptionLevel.IPv6:
          error = 10042; //WSAENOPROTOOPT (Bad protocol option)
          return;
        case SocketOptionLevel.IP:
          if (name != SocketOptionName.NoDelay)
          {
            error = 10042; //WSAENOPROTOOPT (Bad protocol option)
            return;
          }
          break;
        case SocketOptionLevel.Udp:
          if (name == SocketOptionName.NoDelay)
          {
            error = 10042; //WSAENOPROTOOPT (Bad protocol option)
          }
          else
          {
            error = 10022; //WSAEINVAL (Invalid argument)
          }
          return;
        case SocketOptionLevel.Tcp:
          if (name != SocketOptionName.NoDelay)
          {
            error = 10022; //WSAEINVAL (Invalid argument)
            return;
          }
          break;
      }

      try
      {
        bool bval = false;
        int ival = 0;
        switch (name)
        {
          case SocketOptionName.DontLinger:
            jSocket.setSoLinger(false, 0);
            break;
          case SocketOptionName.Linger:
            LingerOption lval = obj_val as LingerOption;
            if (lval != null)
            {
              jSocket.setSoLinger(lval.Enabled, lval.LingerTime);
            }
            else
            {
              error = 10022; //WSAEINVAL (Invalid argument)
            }
            break;
          case SocketOptionName.KeepAlive:
            if (obj_val != null)
            {
              bval = ((int)obj_val == 0)?false:true;
            }
            else
            {
              bval = (int_val == 0)?false:true;
            }
            jSocket.setKeepAlive(bval);
            break;
          case SocketOptionName.NoDelay:
            if (obj_val != null)
            {
              bval = ((int)obj_val == 0)?false:true;
            }
            else
            {
              bval = (int_val == 0)?false:true;
            }
            jSocket.setTcpNoDelay(bval);
            break;
          case SocketOptionName.ReceiveBuffer:
            ival = int_val;
            if (obj_val != null)
            {
              ival = (int) obj_val;
            }
            if (jServerSocket != null)
            {
              jServerSocket.setReceiveBufferSize(ival);
            }
            else
            {
              jSocket.setReceiveBufferSize(ival);
            }
            break;
          case SocketOptionName.ReceiveTimeout:
            ival = int_val;
            if (obj_val != null)
            {
              ival = (int) obj_val;
            }
            if (jServerSocket != null)
            {
              jServerSocket.setSoTimeout(ival);
            }
            else
            {
              jSocket.setSoTimeout(ival);
            }
            break;
          case SocketOptionName.ReuseAddress:
            if (obj_val != null)
            {
              bval = ((int)obj_val == 0)?false:true;
            }
            else
            {
              bval = (int_val == 0)?false:true;
            }
            if (jServerSocket != null)
            {
              jServerSocket.setReuseAddress(bval);
            }
            else
            {
              jSocket.setReuseAddress(bval);
            }
            break;
          case SocketOptionName.SendBuffer:
            ival = int_val;
            if (obj_val != null)
            {
              ival = (int) obj_val;
            }
            jSocket.setSendBufferSize(ival);
            break;
          case SocketOptionName.OutOfBandInline:
            if (obj_val != null)
            {
              bval = ((int)obj_val == 0)?false:true;
            }
            else
            {
              bval = (int_val == 0)?false:true;
            }
            jSocket.setOOBInline(bval);
            break;
          default:
            error = 10022; //WSAEINVAL (Invalid argument)
            break;
        }
      }
      catch (Exception e)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        obj_val = null;
      }
    }

    public void GetSocketOption_obj_internal(SocketOptionLevel level, SocketOptionName name, 
      out object obj_val, out int error)
    {
      obj_val = null;
      error = 0;

      if (jSocket == null && jServerSocket == null)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        return;
      }

      switch (level)
      {
        case SocketOptionLevel.IPv6:
          error = 10042; //WSAENOPROTOOPT (Bad protocol option)
          return;
        case SocketOptionLevel.IP:
          if (name != SocketOptionName.NoDelay)
          {
            error = 10042; //WSAENOPROTOOPT (Bad protocol option)
            return;
          }
          break;
        case SocketOptionLevel.Udp:
          if (name == SocketOptionName.NoDelay)
          {
            error = 10042; //WSAENOPROTOOPT (Bad protocol option)
          }
          else
          {
            error = 10022; //WSAEINVAL (Invalid argument)
          }
          return;
        case SocketOptionLevel.Tcp:
          if (name != SocketOptionName.NoDelay)
          {
            error = 10022; //WSAEINVAL (Invalid argument)
            return;
          }
          break;
      }

      try
      {
        bool bval = false;
        int ival = 0;
        switch (name)
        {
          case SocketOptionName.DontLinger:
            ival = jSocket.getSoLinger();
            if (ival == -1)
            {
              obj_val = 1;
            }
            else
            {
              obj_val = 0;
            }
            break;
          case SocketOptionName.Linger:
            ival = jSocket.getSoLinger();
            if (ival == -1)
            {
              ival = 0;
            }
            LingerOption ret = new LingerOption((ival != 0), ival);
            obj_val = ret;
            break;
          case SocketOptionName.KeepAlive:
            bval = jSocket.getKeepAlive();
            obj_val = ((bval)?1:0);
            break;
          case SocketOptionName.NoDelay:
            bval = jSocket.getTcpNoDelay();
            obj_val = ((bval)?1:0);
            break;
          case SocketOptionName.ReceiveBuffer:
            if (jServerSocket != null)
            {
              ival = jServerSocket.getReceiveBufferSize();
            }
            else
            {
              ival = jSocket.getReceiveBufferSize();
            }
            obj_val = ival;
            break;
          case SocketOptionName.ReceiveTimeout:
            if (jServerSocket != null)
            {
              ival = jServerSocket.getSoTimeout();
            }
            else
            {
              ival = jSocket.getSoTimeout();
            }
            obj_val = ival;
            break;
          case SocketOptionName.ReuseAddress:
            if (jServerSocket != null)
            {
              bval = jServerSocket.getReuseAddress();
            }
            else
            {
              bval = jSocket.getReuseAddress();
            }
            obj_val = ((bval)?1:0);
            break;
          case SocketOptionName.SendBuffer:
            ival = jSocket.getSendBufferSize();
            obj_val = ival;
            break;
          case SocketOptionName.OutOfBandInline:
            bval = jSocket.getOOBInline();
            obj_val = ((bval)?1:0);
            break;
          default:
            error = 10022; //WSAEINVAL (Invalid argument)
            break;
        }
      }
      catch (Exception e)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
        obj_val = null;
      }
    }
    
    public void GetSocketOption_arr_internal(SocketOptionLevel level, SocketOptionName name, 
      ref byte[] byte_val, out int error)
    {
      error = -1;
      throw new NotImplementedException();
    }

    public int WSAIoctl (int ioctl_code, byte [] input, byte [] output, out int error)
    {
      error = -1;
      throw new NotImplementedException();
    }

    public void Shutdown_internal(SocketShutdown how, out int error)
    {
      error = 0;

      if (jServerSocket != null || jSocket == null || !jSocket.isConnected())
      {
        error = 10057; //WSAENOTCONN (Socket is not connected)
        return;
      }

      try
      {
        switch (how)
        {
          case SocketShutdown.Receive: 
                            jSocket.shutdownInput();
                            break;
          case SocketShutdown.Send: 
                    jSocket.shutdownOutput();
                    break;
          case SocketShutdown.Both: 
                    jSocket.shutdownInput();
                    jSocket.shutdownOutput();
                    break;
        }
      }
      catch (Exception e)
      {
        error = 10022; //WSAEINVAL (Invalid argument)
#if DEBUG
        Console.WriteLine("Caught exception during Shutdown_internal - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);
#endif
      }
    }

    private java.io.FileInputStream searchDefaultCacerts()
    {
      try
      {
        string javaHome = java.lang.System.getProperty("java.home");
        if(javaHome == null)
          return null;

        string keyStorePath = javaHome + "/lib/security/cacerts";
        //Console.WriteLine("keyStorePath = {0}", keyStorePath);

        java.io.File f = new java.io.File(keyStorePath);
        if(!f.exists())
          return null;
        return new java.io.FileInputStream(f);
      }
      catch(Exception e)
      {
#if DEBUG
        //todo log it
        Console.WriteLine(e.GetType() + ":" + e.Message + "\n" + e.StackTrace);
#endif
        return null;
      }
    }

    private SSLSocketFactory getSSLSocketFactory()
    {
      SSLSocketFactory factory = null;

      try
      {
        //reading the keyStore path and password from the environment properties
        string keyStorePath = java.lang.System.getProperty("javax.net.ssl.keyStore");
        java.io.FileInputStream keyStoreStream = null;
        if (keyStorePath != null)
        {
          java.io.File file = new java.io.File(keyStorePath);
          if(file.exists())
            keyStoreStream = new java.io.FileInputStream(file);
          else
            keyStoreStream = searchDefaultCacerts();
        }
        else
          keyStoreStream = searchDefaultCacerts();

        string keyStorePassWord = java.lang.System.getProperty("javax.net.ssl.keyStorePassword");
        if (keyStorePassWord == null)
          keyStorePassWord = "changeit";
        char[] passphrase = keyStorePassWord.ToCharArray();        
            
        //initiating SSLContext
        SSLContext ctx = SSLContext.getInstance("TLS");
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        KeyStore ks = KeyStore.getInstance("JKS");
        if (keyStoreStream != null)
          ks.load(keyStoreStream,passphrase);
        else
          ks.load(null,null);
        kmf.init(ks, passphrase);
        tmf.init(ks);
        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        factory = ctx.getSocketFactory();
      }
      catch (Exception e)
      {
        factory = null;
#if DEBUG
        Console.WriteLine("Can't get SSL Socket Factory, the exception is {0}, {1}", e.GetType(), e.Message);
#endif
      }

      return factory;
    }

    public GHSocket ChangeToSSL(EndPoint remote_end)
    {
      if (jSocket == null)
      {
        throw new InvalidOperationException("The underlying socket is null");
      }

      if (!jSocketChannel.isBlocking())
      {
        throw new NotImplementedException("The SSL Socket for non-blocking mode is not supported");
      }

      SSLSocketFactory factory = getSSLSocketFactory();
      if (factory == null)
      {
        throw new ApplicationException("Can't get SSL Socket Factory");
      }

      int err;

      // The problem with local address, when I closed the socket and try to create the new one
      // bounded to the given local address, I receive exception "Address already in use"
      IPEndPoint localEndPoint = null;
//      IPEndPoint localEndPoint = (IPEndPoint) LocalEndPoint_internal(out err);
//      if (err != 0)
//        localEndPoint = null;

      IPEndPoint remoteEndPoint = remote_end as IPEndPoint;
      if (remoteEndPoint == null)
      {
        remoteEndPoint = (IPEndPoint) RemoteEndPoint_internal(out err);
        if (err != 0)
          remoteEndPoint = null;
      }

      java.net.Socket sslSocket = null;
      try
      {
        if (remoteEndPoint != null)
        {
          if (localEndPoint != null)
          {
            sslSocket = factory.createSocket(
              java.net.InetAddress.getByName(remoteEndPoint.Address.ToString()),
              remoteEndPoint.Port,
              java.net.InetAddress.getByName(localEndPoint.Address.ToString()),
              localEndPoint.Port);
          }
          else
          {
            sslSocket = factory.createSocket(
              jSocket, 
              remoteEndPoint.Address.ToString(),
              remoteEndPoint.Port,
              false);
          }

          if (sslSocket != null)
          {
            String[] protocols = { "TLSv1", "SSLv3" };
            ((SSLSocket)sslSocket).setUseClientMode(true);
            ((SSLSocket)sslSocket).startHandshake();
          }

        }
        else
        {
          sslSocket = factory.createSocket();
        }
      }
      catch (Exception e)
      {
        sslSocket = null;
#if DEBUG
        Console.WriteLine("Can't create SSL Socket, the exception is {0}, {1}", e.GetType(), e.Message);
#endif
      }

      if (sslSocket == null)
      {
//        throw new ApplicationException("Can't create SSL Socket");
        // it is important to the Socket class to distinguish if the underlying 
        // handle (GHSocket) is still valid and can be used as non-SSL, or it is already
        // closed by this function and can't be used any more.
        return null;
      }

/*
      string[] arr = ((SSLSocket)sslSocket).getEnabledProtocols();
      if (arr != null)
      {
        foreach (string s in arr)
          Console.WriteLine("s:"+s);
      }
      string [] arr1 = ((SSLSocket)sslSocket).getEnabledCipherSuites();
      if (arr1 != null)
      {
        foreach (string s in arr1)
          Console.WriteLine("s:"+s);
      }
*/

      return new GHStreamSocketSSL(sslSocket);
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.