首页 > 解决方案 > Tor在2个端口上隐藏服务?

问题描述

我正在做一个完全基于 Tor 网络的 p2p 应用程序。该应用程序使用 2 个端口进行通信,例如用于控制命令的 8001 和用于聊天通道的 7001。对等方首先连接到 8001 请求聊天,当我(另一个对等方)接受他的请求时,我尝试在 7001 上连接到他(他应该正在监听并等待我这样做)。我这样做是一种身份验证。

总之,一个对等点在 2 个端口上侦听,一个用于控制(8001),根据他的一方(聊天请求发送方/接收方),他在 7001(聊天)上侦听。协商过程如下(假设控制通道建立在 8001 上) - 我将CHATREQ发送给对等方,然后在 7001 上侦听 - 对等方向我发送CHATOK并尝试连接到我的 7001

我无法理解的问题是,在大多数情况下,与 7001 的连接虽然与 8001 的连接很好,但无法连接!什么可以使一个端口上的连接顺利而另一个端口上的连接失败?有什么我误解了吗?或者它是机制本身的问题(请我想解决这个问题而不是修改整个应用程序来绕过它!所以,不能改变在 2 个单独的端口上工作:))


这是相关的代码部分

1- Socks5连接功能

 public static Socket ConnectViaSocks(ushort Socksport, string RemoteAddress, ushort RemotePort, ref sbyte result)
    {
        Socket torsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        torsock.Connect("127.0.0.1", Socksport);
        // Sending intial request : Authentication
        byte[] AuthReq = { 0x05, 0x01, 0x00 };
        torsock.Send(AuthReq);
        // Getting reply
        byte[] buffer = new byte[2];
        int received = torsock.Receive(buffer);
        if (buffer[1] != 0x00) { torsock.Close(); throw new MyException("SOCKS5 : Authentication error "); }
        // Sending Connect request to a domain (.onion domain)
        byte[] header = { 0x05, 0x01, 0x00, 0x03 };
        byte   DomainLength =(byte) RemoteAddress.Length;
        byte[] DomainName = Encoding.ASCII.GetBytes(RemoteAddress);
        byte[] ConnRequest = new byte[4+1+DomainLength+2]; //Request format = {0x05 0x01 0x00 0x03 Domainlength(1 byte) DomainNmame(Variable Bytes) portNo(2 bytes) }
        System.Buffer.BlockCopy(header      , 0, ConnRequest, 0, header.Length);
        ConnRequest[header.Length] = DomainLength;
        System.Buffer.BlockCopy(DomainName, 0, ConnRequest, header.Length+1, DomainName.Length);
        ConnRequest[header.Length + 1 + DomainName.Length ] = (byte)(RemotePort>>8);
        ConnRequest[header.Length + 1 + DomainName.Length + 1] = (byte)(RemotePort & 255);

        torsock.Send(ConnRequest);
        byte[] buffer2 = new byte[10];
        received = torsock.Receive(buffer2);
        if (buffer2[1] != 0x00) { torsock.Close(); }
        result = (sbyte)buffer2[1];
        return torsock;
    }

2-从我拥有的私钥建立隐藏服务(AKA:临时隐藏服务)命令。

 string command = "ADD_ONION RSA1024:" + PrivateKey + " Port=7001 Port=8001"; // Creating Onion hidden service on ports 7001,8001 
 torctrl.sendCommand(command);

注意: torctrl 是一个套接口的包装器,它将命令字符串发送到 tor 控制端口。


3- 聊天频道建立:

3.1:发起方对等方发送聊天请求:

注意。Globals.SKEY = 不带 .onion 的洋葱地址,

SockThreads.SockTxThread = 在 (contactSocket) 上向对等方发送(消息)的线程

cmd.StrCmd = 将聊天请求格式化为跨应用程序的统一消息格式

Console.WriteLine("[Notice] Sending chat request to " + onion);
message = cmd.StrCmd(Globals.SKEY, Globals.nickname, "CHATREQ", 0, "");
Socket contactSocket = Globals.OnionSocks[onion];
Thread myNewThreadTx = new Thread(() => SockThreads.SockTxThread(contactSocket, message));
myNewThreadTx.Start();

3.2 回复聊天请求

注意:MsgOnion:peer 的地址向我发送了聊天请求

Console.ForegroundColor = System.ConsoleColor.DarkRed;
Console.WriteLine("[Notice] Starting Chat channel creation");
ToPeerMsg = cmd.StrCmd(Globals.SKEY, Globals.nickname, "CHATOK", 0, "");
Thread myNewThreadTx = new Thread(() => SockThreads.SockTxThread(sock, ToPeerMsg));
myNewThreadTx.Start();
Thread.Sleep(1000);
// Connecting to chat port of incoming user
Socket Chatsock = SocketSocks.ConnectViaSocks(9150, MsgOnion + ".onion", 7001, ref result);
if (result == 0)
{ /* Some code to Rx/Tx messages,if come here no problem at all :)*/}

3.3 : 回复 CHAT OK

Thread ChatListenThread = new Thread(() =>SockThreads.SockChatListener());
ChatListenThread.Start();

ChatListenThread:线程在 7001 上侦听,如果有连接,则对聊天进行重要的工作(打开线程、控件等)。要质疑的相关部分:

#region Create listener and accept sockets
TcpListener CtrlListener = new TcpListener(System.Net.IPAddress.Any, 7001);
CtrlListener.Start();

#endregion

#region Wait for a connection
Socket sock;
sock = CtrlListener.AcceptSocket();
Console.WriteLine("[Notice] Chat channel established with peer .... Congrats =) ");

标签: c#winformsp2ptor

解决方案


推荐阅读