pex: remove extra newline in debug message
[project/unetd.git] / main.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
4 */
5 #define _GNU_SOURCE
6 #include <unistd.h>
7 #include <arpa/inet.h>
8 #include <libubox/uloop.h>
9 #include <libubox/blobmsg_json.h>
10 #include "unetd.h"
11
12 struct cmdline_network {
13 struct cmdline_network *next;
14 char *data;
15 };
16
17 static struct cmdline_network *cmd_nets;
18 static const char *hosts_file;
19 const char *mssfix_path = UNETD_MSS_BPF_PATH;
20 const char *data_dir = UNETD_DATA_DIR;
21 int global_pex_port = UNETD_GLOBAL_PEX_PORT;
22 bool debug;
23
24 static void
25 network_write_hosts(struct network *net, FILE *f)
26 {
27 struct network_host *host;
28 char ip[INET6_ADDRSTRLEN];
29
30 if (!net->net_config.local_host)
31 return;
32
33 avl_for_each_element(&net->hosts, host, node) {
34 inet_ntop(AF_INET6, &host->peer.local_addr, ip, sizeof(ip));
35 fprintf(f, "%s\t%s\n", ip, network_host_name(host));
36 }
37 }
38
39 void unetd_write_hosts(void)
40 {
41 struct network *net;
42 char *tmpfile = NULL;
43 FILE *f;
44 int fd;
45
46 if (!hosts_file)
47 return;
48
49 asprintf(&tmpfile, "%s.XXXXXXXX", hosts_file);
50 fd = mkstemp(tmpfile);
51 if (fd < 0) {
52 perror("mkstemp");
53 goto out;
54 }
55
56 chmod(tmpfile, 0644);
57 f = fdopen(fd, "w");
58 if (!f) {
59 close(fd);
60 goto out;
61 }
62
63 avl_for_each_element(&networks, net, node)
64 network_write_hosts(net, f);
65
66 fclose(f);
67
68 if (rename(tmpfile, hosts_file))
69 unlink(tmpfile);
70
71 out:
72 free(tmpfile);
73 }
74
75 static void add_networks(void)
76 {
77 struct cmdline_network *net;
78 static struct blob_buf b;
79 struct blob_attr *name;
80
81 for (net = cmd_nets; net; net = net->next) {
82 blob_buf_init(&b, 0);
83 if (!blobmsg_add_json_from_string(&b, net->data))
84 continue;
85
86 blobmsg_parse(&network_policy[NETWORK_ATTR_NAME], 1, &name,
87 blobmsg_data(b.head), blobmsg_len(b.head));
88 if (!name)
89 continue;
90
91 unetd_network_add(blobmsg_get_string(name), b.head);
92 }
93
94 blob_buf_free(&b);
95 }
96
97 int main(int argc, char **argv)
98 {
99 struct cmdline_network *net;
100 int ch;
101
102 while ((ch = getopt(argc, argv, "D:dh:M:N:P:")) != -1) {
103 switch (ch) {
104 case 'D':
105 data_dir = optarg;
106 break;
107 case 'd':
108 debug = true;
109 break;
110 case 'h':
111 hosts_file = optarg;
112 break;
113 case 'N':
114 net = calloc(1, sizeof(*net));
115 net->next = cmd_nets;
116 net->data = optarg;
117 cmd_nets = net;
118 break;
119 case 'M':
120 mssfix_path = optarg;
121 break;
122 case 'P':
123 global_pex_port = atoi(optarg);
124 break;
125 }
126 }
127
128 uloop_init();
129 unetd_ubus_init();
130 unetd_write_hosts();
131 global_pex_open();
132 add_networks();
133 uloop_run();
134 pex_close();
135 network_free_all();
136 uloop_done();
137
138 return 0;
139 }