summarylogtreecommitdiffstats
path: root/patch5.patch
blob: 9cfbee06a45e27f40da36e9d5897b44545bc72b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
From 1d80b66285765a54a4ed681c27608164756ff980 Mon Sep 17 00:00:00 2001
From: Calvin Owens <calvin@wbinvd.org>
Date: Tue, 4 Feb 2025 11:08:06 -0800
Subject: [PATCH] Portability fixes (#19)

Summary:
Seven fixes for minor issues which show up on BSD and linux+musl:

	1) Add missing "#include <pthread.h>" in a header file.

	2) Add two missing casts for struct sockaddr.

	3) Work around missing dlinfo() on OpenBSD by saving the module
	   paths at open time instead of looking them up later with
	   RTLD_DI_ORIGIN. This also fixes musl. The names are only
	   cosmetic, so if they are subtly different it doesn't matter.

	4) Omit the -lrt and -ldl flags on OpenBSD.

	5) Use <inttypes.h> printf macros and portable udp field names
	   in netconsblaster.

	6) Unfortunately, (5) isn't enough: the runtime semantics of
	   SOCK_RAW are completely different on *BSD, and nothing works.
	   For now, just emit a compile error in netconsblaster for the
	   !linux case. But keep (5) since it's a nice cleanup.

	7) Drop -static-libgcc and -static-libstdc++ from the LDFLAGS in
	   the modules, since they cause errors on musl and don't seem
	   to be necessary on any platform. Also, don't pass LDFLAGS to
	   the compile call, since it causes clang to emit warnings.

Pull Request resolved: https://github.com/facebook/netconsd/pull/19

Reviewed By: htejun

Differential Revision: D69129142

Pulled By: osandov

fbshipit-source-id: ad441b5774bae4e4c6b563218e71b562ce51ba36
---
 Makefile              |  7 ++++++-
 README.md             |  6 +++---
 include/listener.h    |  1 +
 listener.c            |  2 +-
 modules/Makefile      |  6 +++---
 output.c              |  8 +++++---
 util/netconsblaster.c | 26 +++++++++++++++++---------
 7 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/Makefile b/Makefile
index 6909321..50a45f3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 CC ?= gcc
 
-LIBS = -lpthread -lrt -ldl
+LIBS = -lpthread
 CFLAGS ?= -O2 -fPIC
 CFLAGS += -D_GNU_SOURCE -fno-strict-aliasing -Wall -Wextra \
           -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \
@@ -9,6 +9,11 @@ CFLAGS += -D_GNU_SOURCE -fno-strict-aliasing -Wall -Wextra \
 CPPFLAGS ?=
 INCLUDES = -Incrx
 
+UNAME := $(shell uname)
+ifneq ($(UNAME), OpenBSD)
+LIBS += -lrt -ldl
+endif
+
 debug debug32: CFLAGS += -O0 -gdwarf-4 -fno-omit-frame-pointer \
 	                 -fstack-protector-all -fsanitize=address \
                          -fsanitize=undefined
diff --git a/README.md b/README.md
index a2ec1db..15d2808 100644
--- a/README.md
+++ b/README.md
@@ -18,9 +18,9 @@ own custom output module.
 ## Building netconsd
 
 The default Makefile target intended for production use has no external
-dependencies besides glibc. To build it, just say `make`: you'll end up with a
-single executable in this directory called `netconsd`, and a `*.so` file for every
-module in the `modules/` directory.
+dependencies besides glibc. To build it, just say `make` (or `gmake` on BSD):
+you'll end up with a single executable in this directory called `netconsd`, and
+a `*.so` file for every module in the `modules/` directory.
 
 The Makefile includes a few other handy targets:
 
diff --git a/include/listener.h b/include/listener.h
index 832f84b..1b7841b 100644
--- a/include/listener.h
+++ b/include/listener.h
@@ -9,6 +9,7 @@
 #define __LISTENER_H__
 
 #include "threads.h"
+#include <pthread.h>
 
 #define RCVBUF_SIZE	1024
 
diff --git a/listener.c b/listener.c
index 4101b69..6c10aeb 100644
--- a/listener.c
+++ b/listener.c
@@ -124,7 +124,7 @@ static int get_listen_socket(struct sockaddr_in6 *bindaddr)
 	if (ret == -1)
 		fatal("Couldn't set SO_REUSEPORT on socket: %m\n");
 
-	ret = bind(fd, bindaddr, sizeof(*bindaddr));
+	ret = bind(fd, (const struct sockaddr *)bindaddr, sizeof(*bindaddr));
 	if (ret == -1)
 		fatal("Couldn't bind: %m\n");
 
diff --git a/modules/Makefile b/modules/Makefile
index f7c66f1..a981202 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -5,7 +5,7 @@ LDFLAGS ?=
 
 override CFLAGS += -fPIC
 override CXXFLAGS += -std=c++11 -fPIC
-override LDFLAGS += -shared -static-libstdc++ -static-libgcc
+override LDFLAGS += -shared
 INCLUDES = -I../ncrx -I../include
 
 mods = printer.so logger.so
@@ -13,11 +13,11 @@ mods = printer.so logger.so
 all: $(mods)
 
 %.so: %.c
-	$(CC) $< $(CPPFLAGS) $(CFLAGS) $(INCLUDES) $(LDFLAGS) -c -o $(<:.c=.o)
+	$(CC) $< $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -c -o $(<:.c=.o)
 	$(CC) $(<:.c=.o) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
 
 %.so: %.cc
-	$(CXX) $< $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(LDFLAGS) -c -o $(<:.cc=.o)
+	$(CXX) $< $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c -o $(<:.cc=.o)
 	$(CXX) $(<:.cc=.o) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
 
 clean:
diff --git a/output.c b/output.c
index 64d67d9..05ead68 100644
--- a/output.c
+++ b/output.c
@@ -18,6 +18,7 @@
 #include "include/output.h"
 
 static void *output_dlhandles[MAXOUTS];
+static const char *output_dlpaths[MAXOUTS];
 static void (*outputs[MAXOUTS])(int, struct in6_addr *, struct msg_buf *,
 		struct ncrx_msg *);
 static int nr_outputs;
@@ -59,6 +60,7 @@ int register_output_module(char *path, int nr_workers)
 
 	log("Module '%s' registered (#%d@%p)\n", path, nr_outputs, dlsym_addr);
 	output_dlhandles[nr_outputs] = dl;
+	output_dlpaths[nr_outputs] = strdup(path);
 	outputs[nr_outputs] = dlsym_addr;
 	nr_outputs++;
 	return 0;
@@ -72,11 +74,9 @@ void destroy_output_modules(void)
 {
 	int i, ret;
 	void (*mod_exit)(void);
-	char path[PATH_MAX] = {0};
 
 	for (i = 0; i < nr_outputs; i++) {
-		if (dlinfo(output_dlhandles[i], RTLD_DI_ORIGIN, path))
-			strncpy(path, dlerror(), PATH_MAX - 1);
+		const char *path = output_dlpaths[i];
 
 		mod_exit = dlsym(output_dlhandles[i], "netconsd_output_exit");
 		if (mod_exit) {
@@ -88,6 +88,8 @@ void destroy_output_modules(void)
 		ret = dlclose(output_dlhandles[i]);
 		if (ret)
 			warn("dlclose() failed: %s\n", dlerror());
+
+		free((void *)path);
 	}
 }
 
diff --git a/util/netconsblaster.c b/util/netconsblaster.c
index faa2a33..89c7cdc 100644
--- a/util/netconsblaster.c
+++ b/util/netconsblaster.c
@@ -14,6 +14,9 @@
 #include <pthread.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <inttypes.h>
+#include <sys/wait.h>
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/syscall.h>
 #include <arpa/inet.h>
@@ -21,6 +24,10 @@
 #include <netinet/ip6.h>
 #include <netinet/udp.h>
 
+#ifndef __linux__
+#error Sorry, SOCK_RAW is not portable
+#endif
+
 #define fatal(...) \
 do { \
 	printf(__VA_ARGS__); \
@@ -183,17 +190,17 @@ static void make_packet(struct netcons_packet *pkt, const struct in6_addr *src,
 	pkt->l3.ip6_plen = htons(sizeof(pkt->l4) + len);
 	pkt->l3.ip6_hlim = 64;
 
-	nr = snprintf(pkt->payload, len - 1, "%d,%lu,%lu,%s;", md->lvl, md->seq,
-			md->ts, contflag(md->cont));
+	nr = snprintf(pkt->payload, len - 1, "%d,%" PRIu64 ",%" PRIu64 ",%s;",
+		      md->lvl, md->seq, md->ts, contflag(md->cont));
 	if (nr < len)
 		snprintf(pkt->payload + nr, len - nr, "%s", filler);
 	pkt->payload[len - 1] = '\n';
 
-	pkt->l4.source = htons(6666);
-	pkt->l4.dest = htons(*dst_port);
-	pkt->l4.len = htons(sizeof(pkt->l4) + len);
-	pkt->l4.check = htons(udp_csum(&pkt->l3.ip6_src, &pkt->l4,
-			sizeof(pkt->l4) + len));
+	pkt->l4.uh_sport = htons(6666);
+	pkt->l4.uh_dport = htons(*dst_port);
+	pkt->l4.uh_ulen = htons(sizeof(pkt->l4) + len);
+	pkt->l4.uh_sum = htons(udp_csum(&pkt->l3.ip6_src, &pkt->l4,
+			 sizeof(pkt->l4) + len));
 }
 
 static int write_packet(int sockfd, struct netcons_packet *pkt)
@@ -204,7 +211,8 @@ static int write_packet(int sockfd, struct netcons_packet *pkt)
 	};
 
 	memcpy(&bogus.sin6_addr, &pkt->l3.ip6_dst, sizeof(pkt->l3.ip6_dst));
-	return sendto(sockfd, pkt, len, 0, &bogus, sizeof(bogus)) != len;
+	return sendto(sockfd, pkt, len, 0, (const struct sockaddr *)&bogus,
+		      sizeof(bogus)) != len;
 }
 
 static int get_raw_socket(void)
@@ -457,7 +465,7 @@ int main(int argc, char **argv)
 	}
 	finish = now_epoch_ms();
 
-	printf("Wrote %lu packets (%lu pkts/sec)\n", count,
+	printf("Wrote %" PRIu64 " packets (%" PRIu64 " pkts/sec)\n", count,
 			count / (finish - start) * 1000UL);
 	return 0;
 }