paullouisageneau / libjuice

JUICE is a UDP Interactive Connectivity Establishment library
Mozilla Public License 2.0
410 stars 76 forks source link

After setting TRUN, libjuice will always only use relay, no more try P2P, P2P never succeeded #180

Closed fengshangren closed 1 year ago

fengshangren commented 1 year ago

I really do not understand. After setting TRUN, libjuice will always only use TRUN and no longer use P2P. I have tested P2P countless times, and it always fails, all using relay. If TRUN is not set when Juice is created, 90% of P2P direct connections are successful. Please tell me what is causing it or where am I setting it incorrectly

fengshangren commented 1 year ago

https://github.com/paullouisageneau/libjuice/issues/78 I looked at previous feedback with the same problem, but it doesn't seem to be fixed

fengshangren commented 1 year ago
#include "juice/juice.h"

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#ifdef _WIN32
#include <windows.h>
static void sleep(unsigned int secs) { Sleep(secs * 1000); }
#else
#include <unistd.h> // for sleep
#endif

#define BUFFER_SIZE 4096

static juice_agent_t* agent;
static void on_state_changed(juice_agent_t* agent, juice_state_t state, void* user_ptr);
static void on_candidate(juice_agent_t* agent, const char* sdp, void* user_ptr);
static void on_gathering_done(juice_agent_t* agent, void* user_ptr);
static void on_recv(juice_agent_t* agent, const char* data, size_t size, void* user_ptr);

static bool isok = false;
void test_connectivity() {
    juice_set_log_level(JUICE_LOG_LEVEL_DEBUG);

    // Agent 1: Create agent
    juice_config_t config;
    memset(&config, 0, sizeof(config));

    // STUN server
    config.stun_server_host = "47.97.100.165";
    config.stun_server_port = 3478;

    // TURN server
    // Please do not use outside of libjuice tests
    juice_turn_server_t turn_server;
    memset(&turn_server, 0, sizeof(turn_server));
    turn_server.host = "47.97.100.165";
    turn_server.port = 3478;
    turn_server.username = "admin";
    turn_server.password = "123456";
    config.turn_servers = &turn_server;
    config.turn_servers_count = 1;

    config.cb_state_changed = on_state_changed;
    config.cb_candidate = on_candidate;
    config.cb_gathering_done = on_gathering_done;
    config.cb_recv = on_recv;
    config.user_ptr = NULL;

    agent = juice_create(&config);
    juice_gather_candidates(agent);

    while (isok==false)
    {
        sleep(1);
    }

    char localdescription[4096] = {};
    char remotedescription[4096] = {};
    std::cout << "=================================================================================================" << "\n";
    juice_get_local_description(agent, localdescription, sizeof(localdescription));
    std::cout << localdescription;
    std::cout << "=================================================================================================" << "\n";
    std::cin >> remotedescription;
    juice_set_remote_description(agent, remotedescription);

}

// Agent 1: on state changed
static void on_state_changed(juice_agent_t* agent, juice_state_t state, void* user_ptr) {

}

// Agent 1: on local candidate gathered
static void on_candidate(juice_agent_t* agent, const char* sdp, void* user_ptr) {

}

// Agent 1: on local candidates gathering done
static void on_gathering_done(juice_agent_t* agent, void* user_ptr) {
    isok = true;

}

// Agent 1: on message received
static void on_recv(juice_agent_t* agent, const char* data, size_t size, void* user_ptr) {

}

int main()
{
    test_connectivity();
    std::cout << "Hello World!\n";
    Sleep(99999999);
}
fengshangren commented 1 year ago

This is my current usage flow, but there are two problems

  1. I collected all the candidates as you said, and only called juice_set_remote_description, but the P2P direct connection always fails.

  2. Although direct connection is possible, use relay connection

How to use libjuice correctly

paullouisageneau commented 1 year ago

Thank you for reporting.

There is an issue with how you copy paste descriptions:

std::cin >> remotedescription;
juice_set_remote_description(agent, remotedescription);

The >> operator will read a single word from input here, so libjuice will get only the beginning of the description. It's actually surprising you get any connectivity. By the way, you should not read from stdin into a buffer without bound checking as it is unsafe (it allows buffer overflow) and instead you should read into a string.

You could read the entire description with repeated calls to getline until an empty line for instance.

fengshangren commented 1 year ago

I know there is something wrong with std::cin . I mainly demonstrate this process. Do you think there is something wrong with my process? And if it is written like this, will there be a role conflict, and whether the juice caused by the role conflict will only be relayed directly

fengshangren commented 1 year ago

https://github.com/paullouisageneau/libjuice/issues/78

I have the same problem as he feels, but I still don't know how to fix it

My official project is roughly written according to this calling process, but there will be two problems mentioned above.

paullouisageneau commented 1 year ago

I know there is something wrong with std::cin . I mainly demonstrate this process. Do you think there is something wrong with my process?

Please post the actual code, otherwise I can't help you.

And if it is written like this, will there be a role conflict, and whether the juice caused by the role conflict will only be relayed directly

There will be a role conflict, as one side should first call juice_get_local_description then juice_set_remote_description, whereas the other side should call juice_set_remote_description then juice_get_local_description. However, the role conflict should not cause relaying.

fengshangren commented 1 year ago

https://github.com/paullouisageneau/libjuice/issues/78 May I ask what is the cause of the problem reported in this link, and how to solve it in the end

fengshangren commented 1 year ago

controlling_log.txt controlled_log.txt

Can you see the error in the log of the connection between the two ends?

paullouisageneau commented 1 year ago

Can you see the error in the log of the connection between the two ends?

I see no error. UDP datagrams sent from one side never reach the other, so the controlling side eventually choose the relay.

Could you please send the VERBOSE log with and without the TURN server?

fengshangren commented 1 year ago

p2p_controlled_log.txt p2p_controlling_log.txt

I want to know how to improve the success rate of p2p penetration by using libjuice. Now my success rate is very low, perhaps only 5%. But I tested other p2p penetration tools, the same two computers, with a success rate of% 95

fengshangren commented 1 year ago

Tell me how to use libjuice to improve the success rate of p2p nat penetration

paullouisageneau commented 1 year ago

I don't understand, at first you said "If TRUN is not set when Juice is created, 90% of P2P direct connections are successful" now you say "my success rate is very low, perhaps only 5%".

The log without TURN also show a direct connection failure where datagrams from one side never reach the other. How do you pass the descriptions from one computer to the other? If it takes more than a few seconds, NAT traversal might fail.

fengshangren commented 1 year ago

I think you should write a test example of the public network p2p nat. The local example is useless because the local itself can connect directly