Exemple #1
0
 public bool Send(OpCode opcode, byte[] buffer)
 {
     if (buffer == null)
     {
         return(false);
     }
     lock (this)
     {
         if (!socket.Connected)
         {
             return(false);
         }
         WebSocketFrame frame = new WebSocketFrame();
         frame.opcode         = (byte)opcode;
         frame.fin            = true;
         frame.rsv1           = false;
         frame.rsv2           = false;
         frame.rsv3           = false;
         frame.masked         = clientMode; // 客户端需要加密;服务器禁止加密(chrome)
         frame.payload_data   = buffer;
         frame.payload_length = buffer.Length;
         using (MemoryStream s = WebSocketFrame.Pack(frame))
         {
             return(SocketExtension.BeginSend(socket, s.GetBuffer(), 0, (int)s.Position, null));
         }
     }
 }
Exemple #2
0
        private void StartAccept(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = true;

            if (e == null)
            {
                e            = new SocketAsyncEventArgs();
                e.Completed += ProcessAccept;
            }
            e.AcceptSocket = null;
            try
            {
                lock (this)
                {
                    if (!SocketExtension.CleanedUp(server))
                    {
                        willRaiseEvent = server.AcceptAsync(e);
                    }
                }
            }
            catch (Exception) { /*-A-*/ }
            if (!willRaiseEvent)
            {
                ProcessAccept(server, e);
            }
        }
Exemple #3
0
 private static void ReceiveAsync(IntPtr info)
 {
     InternalReceiveAsync(info, false, (socket, socketobject, data, buffer, ofs, count, flags, remoteep, callback) =>
     {
         bool success = false;
         if ((success = SocketExtension.BeginReceive(socket, buffer, ofs, count, flags, (result) =>
         {
             int len = SocketExtension.EndReceive(socket, result, out SocketError error);
             NSJSVirtualMachine machine = socketobject.VirtualMachine;
             machine.Join((sender, state) =>
             {
                 if (len > 0)
                 {
                     for (int i = ofs; i < len; i++)
                     {
                         data[i] = buffer[i];
                     }
                 }
                 if (callback != null)
                 {
                     callback.Call(socketobject, NSJSInt32.New(machine, unchecked ((int)error)), NSJSInt32.New(machine, len));
                 }
             });
         })))
         {
             if (callback != null)
             {
                 callback.CrossThreading = true;
             }
             data.CrossThreading = true;
         }
         return(success);
     });
Exemple #4
0
 private static void Receive(IntPtr info)
 {
     InternalReceive(info, false, (callmode, socket, data, buffer, ofs, count, flags, remoteep) =>
     {
         int len = 0;
         if (callmode == 0)
         {
             SocketExtension.Receive(socket, buffer, 0, count, flags, out len);
         }
         else if (callmode == 1)
         {
             if (SocketExtension.Receive(socket, buffer, ofs, count, flags, out len))
             {
                 for (int i = ofs; i < len; i++)
                 {
                     data[i] = buffer[i];
                 }
             }
         }
         else
         {
             throw new NotSupportedException("callmode");
         }
         return(len);
     });
 }
Exemple #5
0
        private bool HandleUpgradeResponse()
        {
            Func <string> acceptkey = () =>
            {
                using (SHA1 sha1 = SHA1.Create())
                {
                    StringBuilder ss   = new StringBuilder();
                    string        key  = _secWebSocketKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
                    byte[]        hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(key));
                    return(Convert.ToBase64String(hash));
                }
            };
            StringBuilder headers = new StringBuilder();

            headers.Append("HTTP/1.1 101 Switching Protocols\r\n");
            headers.Append("Upgrade: websocket\r\n");
            headers.Append("Connection: Upgrade\r\n");
            headers.AppendFormat("Sec-WebSocket-Accept: {0}\r\n", acceptkey());
            headers.AppendFormat("Sec-WebSocket-Origin: {0}\r\n", _origin);
            headers.AppendFormat("Sec-WebSocket-Location: ws://{0}{1}\r\n\r\n", _host, _rawUri);
            byte[] response = Encoding.UTF8.GetBytes(headers.ToString());
            lock (_signal)
            {
                if (!_socket.Connected || SocketExtension.CleanedUp(_socket))
                {
                    return(false);
                }
                return(SocketExtension.BeginSend(_socket, response, 0, response.Length, null));
            }
        }
Exemple #6
0
 private static void ReceiveFrom(IntPtr info)
 {
     InternalReceive(info, true, (callmode, socket, data, buffer, ofs, count, flags, remoteep) =>
     {
         EndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
         int len           = 0;
         bool success      = false;
         if (callmode == 0)
         {
             success = SocketExtension.ReceiveForm(socket, buffer, 0, count, flags, ref endpoint, out len);
         }
         else if (callmode == 1)
         {
             if ((success = SocketExtension.ReceiveForm(socket, buffer, ofs, count, flags, ref endpoint, out len)))
             {
                 for (int i = ofs; i < len; i++)
                 {
                     data[i] = buffer[i];
                 }
             }
         }
         else
         {
             throw new NotSupportedException("callmode");
         }
         if (success)
         {
             ObjectAuxiliary.Fill(ObjectAuxiliary.ToObject(remoteep.VirtualMachine, endpoint), remoteep);
         }
         return(len);
     });
 }
Exemple #7
0
        private void CloseOrError(bool error)
        {
            bool doEvent = false;

            lock (this)
            {
                if (!cleanUp)
                {
                    doEvent = !cleanUp;
                    SocketExtension.Close(socket);
                    cleanUp = true;
                }
            }
            if (doEvent)
            {
                if (error)
                {
                    DoError(new ErrorEventArgs());
                }
                else
                {
                    DoClose(new CloseEventArgs());
                }
            }
        }
Exemple #8
0
 public void Stop()
 {
     lock (this)
     {
         if (server != null)
         {
             SocketExtension.Close(server);
             server = null;
         }
     }
 }
Exemple #9
0
        private static void AcceptAsync(IntPtr info)
        {
            NSJSFunctionCallbackInfo arguments = NSJSFunctionCallbackInfo.From(info);
            bool success = false;

            do
            {
                SocketContext context = GetSocketContext(arguments.This);
                if (context == null)
                {
                    Throwable.ObjectDisposedException(arguments.VirtualMachine);
                    break;
                }
                SOCKET socket = context.Socket;
                if (socket == null || SocketExtension.CleanedUp(socket))
                {
                    Throwable.ObjectDisposedException(arguments.VirtualMachine);
                    break;
                }
                NSJSFunction callback = arguments.Length > 0 ? arguments[0] as NSJSFunction : null;
                try
                {
                    SocketAsyncEventArgs e = context.AcceptAsync;
                    if (e != null)
                    {
                        break;
                    }
                    e                   = new SocketAsyncEventArgs();
                    e.Completed        += ProcessAccept;
                    e.UserToken         = context;
                    context.AcceptAsync = e;
                    if (callback != null)
                    {
                        NSJSObject socketobject = arguments.This;
                        callback.CrossThreading     = true;
                        context.AcceptAsyncCallback = callback;
                    }
                    if (!socket.AcceptAsync(e))
                    {
                        ProcessAccept(socket, e);
                    }
                    success = true;
                }
                catch (Exception e)
                {
                    Throwable.Exception(arguments.VirtualMachine, e);
                }
            } while (false);
            arguments.SetReturnValue(success);
        }
Exemple #10
0
        private static void Connected(IntPtr info)
        {
            NSJSFunctionCallbackInfo arguments = NSJSFunctionCallbackInfo.From(info);
            SOCKET socket = GetSocket(arguments.This);

            if (socket == null || SocketExtension.CleanedUp(socket))
            {
                Throwable.ObjectDisposedException(arguments.VirtualMachine);
            }
            else
            {
                arguments.SetReturnValue(socket.Connected);
            }
        }
Exemple #11
0
 private int Receive(int ofs, int len)
 {
     try
     {
         lock (_signal)
         {
             if (!_socket.Connected || SocketExtension.CleanedUp(_socket))
             {
                 return(0);
             }
         }
         return(_socket.Receive(_buffer, ofs, len, SocketFlags.None));
     }
     catch (Exception)
     {
         return(0);
     }
 }
Exemple #12
0
 private string ReadString(int len)
 {
     lock (_signal)
     {
         if (!_socket.Connected || SocketExtension.CleanedUp(_socket))
         {
             return(null);
         }
     }
     byte[] buffer;
     if (!SocketExtension.Receive(_socket, 3, out buffer))
     {
         return(null);
     }
     if (buffer == null)
     {
         return(null);
     }
     return(Encoding.UTF8.GetString(buffer));
 }
Exemple #13
0
        private static void Accept(IntPtr info)
        {
            NSJSFunctionCallbackInfo arguments = NSJSFunctionCallbackInfo.From(info);
            SOCKET socket = GetSocket(arguments.This);

            if (socket == null || SocketExtension.CleanedUp(socket))
            {
                Throwable.ObjectDisposedException(arguments.VirtualMachine);
            }
            else
            {
                try
                {
                    arguments.SetReturnValue(New(arguments.VirtualMachine, socket.Accept()));
                }
                catch (Exception e)
                {
                    Throwable.Exception(arguments.VirtualMachine, e);
                }
            }
        }
Exemple #14
0
 private unsafe void ProcessReceive(IAsyncResult result)
 {
     if (_buffer == null)
     {
         _buffer = new byte[SocketExtension.MSS];
     }
     if (result == null)
     {
         int len = SocketExtension.MSS;
         if (frame != null)
         {
             long surplus = frame.payload_surplus;
             if (surplus < len)
             {
                 len = (int)surplus;
             }
         }
         if (!SocketExtension.BeginReceive(socket, _buffer, 0, len,
                                           ProcessReceive))
         {
             CloseOrError(true);
         }
     }
     else
     {
         int len = SocketExtension.EndReceive(socket, result);
         if (len <= 0)
         {
             CloseOrError(false);
         }
         else
         {
             fixed(byte *pinned = _buffer)
             {
                 ProcessReceive(pinned, len);
             }
         }
     }
 }
Exemple #15
0
        public static WebSocketServerHandshake Handshake(object signal, Socket socket)
        {
            if (signal == null || socket == null)
            {
                return(null);
            }
            WebSocketServerHandshake handshake;

            lock (signal)
            {
                if (!socket.Connected || SocketExtension.CleanedUp(socket))
                {
                    return(null);
                }
                handshake = new WebSocketServerHandshake(signal, socket);
            }
            if (handshake == null || !handshake.Handle())
            {
                return(null);
            }
            return(handshake);
        }
        public static unsafe network_address ToNetworkAddress(NetworkEndPoint ep)
        {
            switch (ep.family)
            {
            case NetworkFamily.UdpIpv4:
                return(SocketExtension.MarshalIpV4Address(ep.address, ep.port));

            case NetworkFamily.IPC:
                network_address addr = default(network_address);
                // TODO: Double check this works on ios as well.
#if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
                addr.family.sa_family = (byte)AddressFamily.Unspecified;
#else
                addr.family.sa_family = (ushort)AddressFamily.Unspecified;
#endif
                addr.ipc_handle = *(int *)ep.address;
                addr.length     = 6;
                return(addr);

            default:
                throw new NotImplementedException();
            }
        }
Exemple #17
0
        private bool SendUpgradeRequest()
        {
            lock (_signal)
            {
                if (!_socket.Connected || SocketExtension.CleanedUp(_socket))
                {
                    return(false);
                }
            }
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("GET {0} HTTP/1.1\r\n", _uri.AbsolutePath);

            sb.AppendFormat("Host: {0}:{1}\r\n", _uri.Host, _uri.Port);
            sb.Append("Connection: Upgrade\r\n");
            sb.Append("Pragma: no-cache\r\n");
            sb.Append("Cache-Control: no-cache\r\n");
            sb.Append("Upgrade: websocket\r\n");
            sb.Append("Origin: null\r\n");

            sb.Append("Accept-Encoding: gzip, deflate, br\r\n");
            sb.Append("Accept-Language: zh-CN,zh;q=0.9\r\n");
            sb.Append("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36\r\n");

            sb.AppendFormat("Sec-WebSocket-Key: {0}\r\n", _secWebSocketKey);
            sb.Append("Sec-WebSocket-Origin: null\r\n");
            sb.Append("Sec-WebSocket-Version: 13\r\n");
            sb.Append("Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n");

            byte[] request = Encoding.UTF8.GetBytes(sb.ToString());
            if (!SocketExtension.BeginSend(_socket, request, 0, request.Length, null))
            {
                return(false);
            }
            return(true);
        }
 public unsafe int SendMessage(void *iov, int iov_len, ref network_address address)
 {
     return(SocketExtension.SendMessageEx(m_SocketHandle, iov, iov_len, ref address));
 }
        public async Task <SocketReceiveFromResult> ReceiveFromAsync(ArraySegment <byte> buffer)
        {
            byte[] datagram = new byte[262 + buffer.Count];

            SocketReceiveFromResult result = await _udpSocket.ReceiveFromAsync(datagram, SocketFlags.None, SocketExtension.GetEndPointAnyFor(_udpSocket.AddressFamily));

            if (result.ReceivedBytes < 10)
            {
                throw new SocksProxyException("Incomplete SOCKS5 datagram was received.");
            }

            EndPoint remoteEP;

            switch ((SocksAddressType)datagram[3])
            {
            case SocksAddressType.IPv4Address:
            {
                byte[] address = new byte[4];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 4);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 4, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.IPv6Address:
            {
                byte[] address = new byte[16];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 16);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 16, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.DomainName:
            {
                int length = datagram[3 + 1];

                byte[] address = new byte[length];
                Buffer.BlockCopy(datagram, 3 + 1 + 1, address, 0, length);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 1 + length, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new DomainEndPoint(Encoding.ASCII.GetString(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            default:
                throw new NotSupportedException("SocksAddressType not supported.");
            }

            int addressSize;

            switch (remoteEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
                addressSize = 4;
                break;

            case AddressFamily.InterNetworkV6:
                addressSize = 16;
                break;

            case AddressFamily.Unspecified:
                addressSize = 1 + (remoteEP as DomainEndPoint).Address.Length;
                break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            int dataOffset = 6 + addressSize;
            int dataSize   = result.ReceivedBytes - dataOffset;

            if (dataSize > buffer.Count)
            {
                dataSize = buffer.Count;
            }

            ArraySegment <byte> recvData = new ArraySegment <byte>(datagram, dataOffset, dataSize);

            recvData.CopyTo(buffer);

            if (_relayEP == null)
            {
                _relayEP = result.RemoteEndPoint; //set new relay ep
            }
            return(new SocketReceiveFromResult()
            {
                ReceivedBytes = dataSize, RemoteEndPoint = remoteEP
            });
        }
 public Task <SocketReceiveFromResult> ReceiveFromAsync(ArraySegment <byte> buffer)
 {
     return(_socket.ReceiveFromAsync(buffer, SocketFlags.None, SocketExtension.GetEndPointAnyFor(_socket.AddressFamily)));
 }
Exemple #21
0
        private static void ConnectAsync(IntPtr info)
        {
            NSJSFunctionCallbackInfo arguments = NSJSFunctionCallbackInfo.From(info);
            bool success = false;

            do
            {
                if (arguments.Length <= 0)
                {
                    Throwable.ObjectDisposedException(arguments.VirtualMachine);
                    break;
                }
                SocketContext context = GetSocketContext(arguments.This);
                if (context == null)
                {
                    Throwable.ObjectDisposedException(arguments.VirtualMachine);
                    break;
                }
                SOCKET socket = context.Socket;
                if (socket == null || SocketExtension.CleanedUp(socket))
                {
                    Throwable.ObjectDisposedException(arguments.VirtualMachine);
                    break;
                }
                EndPoint remoteEP = ObjectAuxiliary.ToEndPoint(arguments[0]);
                int      cbsolt   = 1;
                if (remoteEP == null)
                {
                    IPAddress address = ObjectAuxiliary.ToAddress(arguments[0]);
                    if (address == null)
                    {
                        break;
                    }
                    int port = arguments.Length > 1 ? ((arguments[1] as NSJSInt32)?.Value).GetValueOrDefault() : 0;
                    remoteEP = new IPEndPoint(address, port);
                    cbsolt++;
                }
                if (remoteEP == null)
                {
                    break;
                }
                NSJSFunction callback = arguments.Length > cbsolt ? arguments[cbsolt] as NSJSFunction : null;
                try
                {
                    SocketAsyncEventArgs e = context.ConnectedAsync;
                    if (e != null)
                    {
                        break;
                    }
                    else
                    {
                        e                      = new SocketAsyncEventArgs();
                        e.Completed           += ProcessConnected;
                        e.UserToken            = context;
                        context.ConnectedAsync = e;
                    }
                    e.RemoteEndPoint = remoteEP;
                    if (callback != null)
                    {
                        callback.CrossThreading        = true;
                        context.ConnectedAsyncCallback = callback;
                    }
                    if (!socket.ConnectAsync(e))
                    {
                        ProcessConnected(socket, e);
                    }
                    success = true;
                }
                catch (Exception e)
                {
                    Throwable.Exception(arguments.VirtualMachine, e);
                }
            } while (false);
            arguments.SetReturnValue(success);
        }