blob: 929bcc196af51f2bdd0f5a1074986fc1efe19e27 [file] [log] [blame]
Amna38768302023-08-21 11:51:56 -04001/*
2 * Copyright (C) 2004-2023 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#include "dnc.h"
18#include "common.h"
Adrien Béraudc1cac452023-08-22 20:32:36 -040019
Amna38768302023-08-21 11:51:56 -040020#include <string>
21#include <vector>
22#include <iostream>
23#include <unistd.h>
24#include <getopt.h>
Adrien Béraudecde63f2023-08-26 18:11:21 -040025#include <fmt/std.h>
Amna38768302023-08-21 11:51:56 -040026#include <netinet/in.h>
27
28struct dhtnc_params
29{
30 bool help {false};
31 bool version {false};
32 bool listen {false};
Adrien Béraudecde63f2023-08-26 18:11:21 -040033 bool verbose {false};
34 std::filesystem::path path {};
35 std::string bootstrap {};
36 std::string remote_host {};
37 in_port_t remote_port {};
Amna38768302023-08-21 11:51:56 -040038 dht::InfoHash peer_id {};
39};
40
41static const constexpr struct option long_options[]
42 = {{"help", no_argument, nullptr, 'h'},
Adrien Béraudecde63f2023-08-26 18:11:21 -040043 {"version", no_argument, nullptr, 'V'},
44 {"verbose", no_argument, nullptr, 'v'},
Amna38768302023-08-21 11:51:56 -040045 {"port", required_argument, nullptr, 'p'},
46 {"ip", required_argument, nullptr, 'i'},
47 {"listen", no_argument, nullptr, 'l'},
Adrien Béraudecde63f2023-08-26 18:11:21 -040048 {"bootstrap", required_argument, nullptr, 'b'},
49 {"id_path", required_argument, nullptr, 'I'},
Amna38768302023-08-21 11:51:56 -040050 {nullptr, 0, nullptr, 0}};
51
52dhtnc_params
53parse_args(int argc, char** argv)
54{
55 dhtnc_params params;
56 int opt;
Adrien Béraudecde63f2023-08-26 18:11:21 -040057 while ((opt = getopt_long(argc, argv, "hvI:p:i:", long_options, nullptr)) != -1) {
58 fmt::print("opt: {} {}\n", opt, optarg);
Amna38768302023-08-21 11:51:56 -040059 switch (opt) {
60 case 'h':
61 params.help = true;
62 break;
Adrien Béraudecde63f2023-08-26 18:11:21 -040063 case 'V':
Amna38768302023-08-21 11:51:56 -040064 params.version = true;
65 break;
Adrien Béraudecde63f2023-08-26 18:11:21 -040066 case 'v':
67 params.verbose = true;
68 break;
Amna38768302023-08-21 11:51:56 -040069 case 'p':
Adrien Béraudecde63f2023-08-26 18:11:21 -040070 params.remote_port = std::stoi(optarg);
Amna38768302023-08-21 11:51:56 -040071 break;
72 case 'i':
Adrien Béraudecde63f2023-08-26 18:11:21 -040073 params.remote_host = optarg;
Amna38768302023-08-21 11:51:56 -040074 break;
75 case 'l':
76 params.listen = true;
77 break;
78 case 'b':
Adrien Béraudecde63f2023-08-26 18:11:21 -040079 params.bootstrap = optarg;
Amna38768302023-08-21 11:51:56 -040080 break;
Adrien Béraudecde63f2023-08-26 18:11:21 -040081 case 'I':
82 params.path = optarg;
Amna38768302023-08-21 11:51:56 -040083 break;
84 default:
85 std::cerr << "Invalid option" << std::endl;
86 exit(EXIT_FAILURE);
87 }
88 }
89
90 // If not listening, the peer_id argument is required
91 if (!params.listen) {
92 if (optind < argc) {
93 params.peer_id = dht::InfoHash(argv[optind]);
94 optind++; // Move to the next argument
95 } else {
96 std::cerr << "Error: Missing peer_id argument.\n";
97 exit(EXIT_FAILURE);
98 }
99 }
100
101 // default values
Adrien Béraudecde63f2023-08-26 18:11:21 -0400102 if (params.remote_port == 0)
103 params.remote_port = 2000;
104 if (params.remote_host.empty())
105 params.remote_host = "127.0.0.1";
106 if (params.bootstrap.empty())
107 params.bootstrap = "bootstrap.jami.net";
108 if (params.path.empty())
109 params.path = std::filesystem::path(getenv("HOME")) / ".dhtnet";
Amna38768302023-08-21 11:51:56 -0400110 return params;
111}
112
113static void
114setSipLogLevel()
115{
116 char* envvar = getenv("SIPLOGLEVEL");
117
118 int level = 0;
119
120 if (envvar != nullptr) {
121 level = std::stoi(envvar);
122
123 // From 0 (min) to 6 (max)
124 level = std::max(0, std::min(level, 6));
125 }
126
127 pj_log_set_level(level);
128 pj_log_set_log_func([](int level, const char* data, int /*len*/) {
129 });
130}
131
132int
133main(int argc, char** argv)
134{
Adrien Béraudecde63f2023-08-26 18:11:21 -0400135 fmt::print("dnc 1.0\n");
Amna38768302023-08-21 11:51:56 -0400136 setSipLogLevel();
137 auto params = parse_args(argc, argv);
Adrien Béraudecde63f2023-08-26 18:11:21 -0400138 auto identity = dhtnet::loadIdentity(params.path);
139 fmt::print("Loaded identity: {} from {}\n", identity.second->getId(), params.path);
Amna38768302023-08-21 11:51:56 -0400140
141 std::unique_ptr<dhtnet::Dnc> dhtnc;
142 if (params.listen) {
Amna38768302023-08-21 11:51:56 -0400143 // create dnc instance
Adrien Béraudecde63f2023-08-26 18:11:21 -0400144 dhtnc = std::make_unique<dhtnet::Dnc>(params.path, identity, params.bootstrap);
Amna38768302023-08-21 11:51:56 -0400145 } else {
Adrien Béraudecde63f2023-08-26 18:11:21 -0400146 dhtnc = std::make_unique<dhtnet::Dnc>(params.path,
147 identity,
148 params.bootstrap,
Amna38768302023-08-21 11:51:56 -0400149 params.peer_id,
Adrien Béraudecde63f2023-08-26 18:11:21 -0400150 params.remote_host,
151 params.remote_port);
Amna38768302023-08-21 11:51:56 -0400152 }
153 dhtnc->run();
154}