Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit 59faf3c

Browse files
committed
surveyor: add broken recvmsg
1 parent 974cddf commit 59faf3c

File tree

2 files changed

+301
-23
lines changed

2 files changed

+301
-23
lines changed

infra/surveyor/default.nix

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,31 @@ with rec
1414
};
1515

1616
runTest = test: pkgs.runCommand "test"
17-
{ buildInputs = [ pkgs.netcat pkgs.curl pkgs.haskellPackages.wai-app-static ] ;}
17+
{ buildInputs = [ pkgs.strace pkgs.netcat pkgs.curl pkgs.haskellPackages.wai-app-static pkgs.dnsmasq pkgs.dnsutils ] ;}
1818
(test + "\n" + "touch $out");
1919

20+
runDNS = hosts: port:
21+
''
22+
trap 'echo $SRV_TEST_PIDS | xargs kill -9' EXIT
23+
SRV_TEST_PIDS="''${SRV_TEST_PIDS:-""}"
24+
NIX_REDIRECTS=/etc/hosts=${setHosts hosts} \
25+
LD_PRELOAD="${pkgs.libredirect}/lib/libredirect.so" \
26+
dnsmasq -p ${builtins.toString port} --log-facility=- &
27+
SRV_TEST_PIDS="$SRV_TEST_PIDS $!"
28+
echo $SRV_TEST_PIDS
29+
while ! nc -z 127.0.0.1 ${builtins.toString port}; do
30+
echo waiting for port ${builtins.toString port}
31+
sleep 1
32+
done
33+
'';
34+
2035
runPort = port:
2136
''
2237
trap 'echo $SRV_TEST_PIDS | xargs kill -9' EXIT
2338
SRV_TEST_PIDS="''${SRV_TEST_PIDS:-""}"
2439
warp -d ${apiPort port} -p ${builtins.toString port} &
2540
SRV_TEST_PIDS="$SRV_TEST_PIDS $!"
41+
echo $SRV_TEST_PIDS
2642
while ! nc -z 127.0.0.1 ${builtins.toString port}; do
2743
echo waiting for port ${builtins.toString port}
2844
sleep 1
@@ -96,6 +112,35 @@ let tests =
96112
LD_PRELOAD="${surveyor}/lib/surveyor.so ${pkgs.libredirect}/lib/libredirect.so" \
97113
curl does.not.exist | grep -q '1235'
98114
'';
115+
116+
# Accessing www.example.com:80 reroutes to localhost:1234 through DNS server
117+
test_redirectHostsDNS =
118+
''
119+
${runPort 1234}
120+
#strace -f -e trace=network \
121+
dnsmasq \
122+
--address=/www.example.com/0.0.0.42 \
123+
--address=/www.example.com/:: \
124+
-p 8053 --no-ping --log-facility=- &
125+
echo dnsmasq is $!
126+
127+
while ! nc -z 127.0.0.1 8053; do
128+
echo waiting for dnsmasq
129+
sleep 1
130+
done
131+
132+
strace -f -e trace=network \
133+
-E SRV_MAP="0.0.0.42:80:127.0.0.1:1234 127.0.0.1:53:127.0.0.1:8053" \
134+
-E LD_PRELOAD="${surveyor}/lib/surveyor.so" \
135+
nslookup www.example.com
136+
137+
exit 55
138+
139+
strace -f -e trace=network \
140+
-E SRV_MAP="0.0.0.42:80:127.0.0.1:1234 127.0.0.1:53:127.0.0.1:8053" \
141+
-E LD_PRELOAD="${surveyor}/lib/surveyor.so" \
142+
curl -s www.example.com | grep -q '1234'
143+
'';
99144
}; in
100145

101146
{ inherit surveyor;

infra/surveyor/surveyor.c

Lines changed: 255 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@
1212

1313
int (*super_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
1414

15+
ssize_t (*super_sendto)(int sockfd, const void *buf, size_t len, int flags,
16+
const struct sockaddr *dest_addr, socklen_t addrlen);
17+
18+
ssize_t (*super_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
19+
20+
ssize_t (*super_recvfrom)(int sockfd, void *buf, size_t len, int flags,
21+
struct sockaddr *src_addr, socklen_t *addrlen);
22+
23+
ssize_t (*super_recvmsg)(int sockfd, struct msghdr *msg, int flags);
24+
1525
typedef struct
1626
{
1727
// Port to map from. If "0" or "*" is given, maps from all ports.
@@ -28,10 +38,31 @@ typedef struct
2838

2939
} srv_mapping;
3040

31-
3241
srv_mapping *mappings;
3342
unsigned short n_mappings;
3443

44+
45+
// TODO: attribute hidden
46+
srv_mapping * srv_find_mapping(const struct sockaddr_in *addr_in)
47+
{
48+
for (int i = 0; i < n_mappings; i ++)
49+
{
50+
if (mappings[i].addr_from == NULL ||
51+
(*mappings[i].addr_from).s_addr == (addr_in->sin_addr).s_addr)
52+
{
53+
if(mappings[i].port_from == 0 ||
54+
mappings[i].port_from == addr_in->sin_port)
55+
{
56+
fprintf(stderr, "WE HAVE A MATCH!!!!!!\n");
57+
return mappings + i;
58+
}
59+
}
60+
}
61+
62+
return NULL;
63+
}
64+
65+
3566
void _fini(void)
3667
{
3768
if (mappings != NULL)
@@ -172,6 +203,30 @@ void _init(void)
172203
fprintf(stderr, "dlsym(connect) failed: %s\n", err);
173204
exit(42);
174205
}
206+
207+
super_sendto = dlsym(RTLD_NEXT, "sendto");
208+
if ((err = dlerror()) != NULL) {
209+
fprintf(stderr, "dlsym(sendto) failed: %s\n", err);
210+
exit(42);
211+
}
212+
213+
super_sendmsg = dlsym(RTLD_NEXT, "sendmsg");
214+
if ((err = dlerror()) != NULL) {
215+
fprintf(stderr, "dlsym(sendmsg) failed: %s\n", err);
216+
exit(42);
217+
}
218+
219+
super_recvmsg = dlsym(RTLD_NEXT, "recvmsg");
220+
if ((err = dlerror()) != NULL) {
221+
fprintf(stderr, "dlsym(recvmsg) failed: %s\n", err);
222+
exit(42);
223+
}
224+
225+
super_recvfrom = dlsym(RTLD_NEXT, "recvfrom");
226+
if ((err = dlerror()) != NULL) {
227+
fprintf(stderr, "dlsym(recvfrom) failed: %s\n", err);
228+
exit(42);
229+
}
175230
}
176231

177232
int connect(int sockfd, const struct sockaddr *dest_addr, socklen_t dest_len)
@@ -187,46 +242,224 @@ int connect(int sockfd, const struct sockaddr *dest_addr, socklen_t dest_len)
187242
static struct sockaddr_in *dest_addr_in;
188243
dest_addr_in = (struct sockaddr_in *)dest_addr;
189244

190-
bool found = false;
191-
srv_mapping mapping;
245+
srv_mapping * mapping = srv_find_mapping(dest_addr_in);
192246

193-
for (int i = 0; i < n_mappings; i ++)
247+
if(mapping)
194248
{
195-
mapping = mappings[i];
196-
if (mapping.addr_from == NULL ||
197-
(*mapping.addr_from).s_addr == (dest_addr_in->sin_addr).s_addr)
249+
static struct sockaddr_storage new_dest_addr;
250+
memcpy(&new_dest_addr, dest_addr, dest_len);
251+
252+
static struct sockaddr_in *new_dest_addr_in;
253+
new_dest_addr_in = (struct sockaddr_in *)&new_dest_addr;
254+
if(mapping->port_to != 0)
198255
{
199-
if(mapping.port_from == 0 ||
200-
mapping.port_from == dest_addr_in->sin_port)
201-
{
202-
fprintf(stderr, "WE HAVE A MATCH!!!!!!\n");
203-
found = true;
204-
break;
205-
}
256+
new_dest_addr_in->sin_port = mapping->port_to;
206257
}
258+
259+
if(mapping->addr_to != NULL)
260+
{
261+
new_dest_addr_in->sin_addr = *mapping->addr_to;
262+
}
263+
return super_connect(sockfd, (struct sockaddr *)&new_dest_addr, dest_len);
264+
265+
} else
266+
{
267+
return super_connect(sockfd, dest_addr, dest_len);
268+
207269
}
270+
}
208271

209-
if(found)
272+
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
273+
const struct sockaddr *dest_addr, socklen_t addrlen)
274+
{
275+
fprintf(stderr, "Entering sendto(2)\n");
276+
277+
if (dest_addr->sa_family != AF_INET) {
278+
fprintf(stderr, "No AF_INET, skipping\n");
279+
return super_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
280+
}
281+
282+
static struct sockaddr_in *dest_addr_in;
283+
dest_addr_in = (struct sockaddr_in *)dest_addr;
284+
285+
srv_mapping * mapping = srv_find_mapping(dest_addr_in);
286+
287+
if(mapping)
210288
{
211289
static struct sockaddr_storage new_dest_addr;
212-
memcpy(&new_dest_addr, dest_addr, dest_len);
290+
memcpy(&new_dest_addr, dest_addr, addrlen);
213291

214292
static struct sockaddr_in *new_dest_addr_in;
215293
new_dest_addr_in = (struct sockaddr_in *)&new_dest_addr;
216-
if(mapping.port_to != 0)
294+
if(mapping->port_to != 0)
217295
{
218-
new_dest_addr_in->sin_port = mapping.port_to;
296+
new_dest_addr_in->sin_port = mapping->port_to;
219297
}
220298

221-
if(mapping.addr_to != NULL)
299+
if(mapping->addr_to != NULL)
222300
{
223-
new_dest_addr_in->sin_addr = *mapping.addr_to;
301+
new_dest_addr_in->sin_addr = *mapping->addr_to;
224302
}
225-
return super_connect(sockfd, (struct sockaddr *)&new_dest_addr, dest_len);
303+
return super_sendto(sockfd, buf, len, flags, (struct sockaddr *)&new_dest_addr, addrlen);
226304

227305
} else
228306
{
229-
return super_connect(sockfd, dest_addr, dest_len);
307+
return super_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
308+
309+
}
310+
311+
}
312+
313+
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
314+
{
315+
fprintf(stderr, "Entering sendmsg(2)\n");
316+
317+
if(msg->msg_name == NULL)
318+
{
319+
fprintf(stderr, "No msg_name, skipping\n");
320+
return super_sendmsg(sockfd, msg, flags);
321+
322+
}
323+
324+
static struct sockaddr_in *dest_addr_in;
325+
dest_addr_in = (struct sockaddr_in *)msg->msg_name;
326+
327+
if(dest_addr_in->sin_family != AF_INET)
328+
{
329+
fprintf(stderr, "No AF_INET, skipping\n");
330+
return super_sendmsg(sockfd, msg, flags);
331+
}
332+
333+
srv_mapping * mapping = srv_find_mapping(dest_addr_in);
334+
335+
if(mapping)
336+
{
337+
338+
static struct sockaddr_storage new_dest_addr;
339+
memcpy(&new_dest_addr, dest_addr_in, msg->msg_namelen);
340+
341+
static struct sockaddr_in *new_dest_addr_in;
342+
new_dest_addr_in = (struct sockaddr_in *)&new_dest_addr;
343+
344+
if(mapping->port_to != 0)
345+
{
346+
new_dest_addr_in->sin_port = mapping->port_to;
347+
}
348+
349+
if(mapping->addr_to != NULL)
350+
{
351+
new_dest_addr_in->sin_addr = *mapping->addr_to;
352+
}
353+
354+
static struct msghdr new_msg;
355+
memcpy(&new_msg, msg, sizeof(*msg));
356+
357+
new_msg.msg_name = (void*) new_dest_addr_in;
358+
359+
return super_sendmsg(sockfd, &new_msg, flags);
360+
361+
362+
} else
363+
{
364+
return super_sendmsg(sockfd, msg, flags);
365+
}
366+
}
367+
368+
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
369+
struct sockaddr *src_addr, socklen_t *addrlen)
370+
{
371+
fprintf(stderr, "Entering recvfrom(2)\n");
372+
373+
if (src_addr->sa_family != AF_INET) {
374+
fprintf(stderr, "No AF_INET, skipping\n");
375+
return super_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
376+
}
377+
378+
static struct sockaddr_in *src_addr_in;
379+
src_addr_in = (struct sockaddr_in *)src_addr;
380+
381+
srv_mapping * mapping = srv_find_mapping(src_addr_in);
382+
383+
if(mapping)
384+
{
385+
386+
in_port_t old_port = src_addr_in->sin_port;
387+
struct in_addr old_addr = src_addr_in->sin_addr;
388+
389+
if(mapping->port_to != 0)
390+
{
391+
src_addr_in->sin_port = mapping->port_to;
392+
}
393+
394+
if(mapping->addr_to != NULL)
395+
{
396+
src_addr_in->sin_addr = *mapping->addr_to;
397+
}
398+
399+
ssize_t res;
400+
res = super_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
401+
402+
src_addr_in->sin_port = old_port;
403+
src_addr_in->sin_addr = old_addr;
404+
405+
return res;
406+
} else
407+
{
408+
return super_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
409+
}
410+
}
230411

412+
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
413+
{
414+
fprintf(stderr, "Entering recvmsg(2)\n");
415+
416+
if(msg->msg_name == NULL)
417+
{
418+
fprintf(stderr, "No msg_name, skipping\n");
419+
return super_sendmsg(sockfd, msg, flags);
231420
}
421+
422+
423+
struct sockaddr_in *src_addr_in = msg->msg_name;
424+
425+
fprintf(stderr, "recvmsg: msg_namelen: %d\n", msg->msg_namelen);
426+
fprintf(stderr, "recvmsg: AF_INET: %d vs %d\n", AF_INET, src_addr_in->sin_family);
427+
428+
if(src_addr_in->sin_family != AF_INET)
429+
{
430+
fprintf(stderr, "recvmsg: No AF_INET, skipping\n");
431+
return super_recvmsg(sockfd, msg, flags);
432+
}
433+
434+
srv_mapping * mapping = srv_find_mapping(src_addr_in);
435+
436+
if(mapping)
437+
{
438+
in_port_t old_port = src_addr_in->sin_port;
439+
struct in_addr old_addr = src_addr_in->sin_addr;
440+
441+
if(mapping->port_to != 0)
442+
{
443+
src_addr_in->sin_port = mapping->port_to;
444+
}
445+
446+
if(mapping->addr_to != NULL)
447+
{
448+
src_addr_in->sin_addr = *mapping->addr_to;
449+
}
450+
451+
ssize_t res;
452+
res = super_recvmsg(sockfd, msg, flags);
453+
454+
src_addr_in->sin_port = old_port;
455+
src_addr_in->sin_addr = old_addr;
456+
457+
return res;
458+
459+
460+
} else
461+
{
462+
return super_recvmsg(sockfd, msg, flags);
463+
}
464+
232465
}

0 commit comments

Comments
 (0)