private async Task HandleConnectRequestAsync(Request request, Memory <byte> buffer, CancellationToken cancellationToken = default) { // Connect to remote endpoint. EndpointSocket = ClientSocket.CreateNewOfSameType(); EndpointSocket.Bind(new IPEndPoint(EndpointInterface, 0 /* any */)); var error = null as SocketError?; try { switch (request) { case IpRequest ipRequest: EndpointSocket = await EndpointSocket.ConnectAsync(ipRequest.Address, ipRequest.Port); break; case DomainNameRequest domainRequest: EndpointSocket = await EndpointSocket.ConnectAsync(domainRequest.DomainName, domainRequest.Port); break; default: throw new Exception("Unknown request type."); } } catch (SocketException e) { error = e.SocketErrorCode; } var localEndpoint = EndpointSocket?.LocalEndPoint as IPEndPoint ?? new IPEndPoint(0, 0); var remoteEndpoint = EndpointSocket?.RemoteEndPoint as IPEndPoint ?? new IPEndPoint(0, 0); // The bind address and port should be the server local values during a CONNECT. var localAddress = localEndpoint.Address; if (localAddress.IsIPv4MappedToIPv6) { localAddress = localAddress.MapToIPv4(); } var(portHigh, portLow) = Helpers.GetBytesFromPort(localEndpoint.Port); // Select the reply code based on any errors. var replyField = Helpers.GetSocksReply(error); // Send reply to client. var replyLength = 0; buffer.Span[0] = 0x05; // VERSION buffer.Span[1] = replyField; // REPLY. buffer.Span[2] = 0x00; // RESERVED. if (localAddress.AddressFamily == AddressFamily.InterNetwork) { buffer.Span[3] = 0x01; // ADDRESS TYPE (IPv4). localAddress.TryWriteBytes(buffer.Span.Slice(4, 4), out int written); buffer.Span[8] = portHigh; buffer.Span[9] = portLow; replyLength = 10; } else if (localAddress.AddressFamily == AddressFamily.InterNetworkV6) { buffer.Span[3] = 0x04; // ADDRESS TYPE (IPv6). localAddress.TryWriteBytes(buffer.Span.Slice(4, 16), out int written); buffer.Span[20] = portHigh; buffer.Span[21] = portLow; replyLength = 22; } else { throw new Exception("Unknown server-local bind address type."); } // Send a response to client regardless of failure. await ClientSocket.SendAsync(buffer.Slice(0, replyLength), cancellationToken); var sock = new Socket(SocketType.Dgram, ProtocolType.Udp); var buf = new byte[4096]; // In a failure scenario, ensure the SOCKS process does not continue. if (error != null) { throw new SocksException($"The connection failed gracefully with `{error}`."); } }