Skip to content

Commit 6a1975d

Browse files
author
jasmin
committedApr 16, 2021
- fix listen address; - list addresses in api call; - --cidr6 parameter; - add test; - fix api test script;
1 parent 8cc216f commit 6a1975d

File tree

5 files changed

+118
-21
lines changed

5 files changed

+118
-21
lines changed
 

‎Makefile.am

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ AM_CFLAGS = @GLIB_CFLAGS@ @SLIRP_CFLAGS@ @LIBCAP_CFLAGS@ @LIBSECCOMP_CFLAGS@
55
noinst_LIBRARIES = libparson.a
66

77
AM_TESTS_ENVIRONMENT = PATH="$(abs_top_builddir):$(PATH)"
8-
TESTS = tests/test-slirp4netns.sh tests/test-slirp4netns-configure.sh tests/test-slirp4netns-exit-fd.sh tests/test-slirp4netns-ready-fd.sh tests/test-slirp4netns-api-socket.sh tests/test-slirp4netns-disable-host-loopback.sh tests/test-slirp4netns-cidr.sh tests/test-slirp4netns-outbound-addr.sh tests/test-slirp4netns-disable-dns.sh tests/test-slirp4netns-seccomp.sh tests/test-slirp4netns-macaddress.sh
8+
TESTS = tests/test-slirp4netns.sh tests/test-slirp4netns-configure.sh tests/test-slirp4netns-exit-fd.sh tests/test-slirp4netns-ready-fd.sh tests/test-slirp4netns-api-socket.sh tests/test-slirp4netns-disable-host-loopback.sh tests/test-slirp4netns-cidr.sh tests/test-slirp4netns-outbound-addr.sh tests/test-slirp4netns-disable-dns.sh tests/test-slirp4netns-seccomp.sh tests/test-slirp4netns-macaddress.sh tests/test-slirp4netns-ipv6.sh
99

1010
EXTRA_DIST = \
1111
slirp4netns.1.md \

‎api.c

+21-3
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,8 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
207207
}
208208
if (fwd->is_ipv6) {
209209
if (guest_addr_s == NULL || guest_addr_s[0] == '\0') {
210-
guest_addr_s = "fd00::100";
211-
}
212-
if (inet_pton(AF_INET6, guest_addr_s, &fwd->guest_addr6) != 1) {
210+
fwd->guest_addr6 = ctx->cfg->recommended_vguest6;
211+
} else if (inet_pton(AF_INET6, guest_addr_s, &fwd->guest_addr6) != 1) {
213212
const char *err = "{\"error\":{\"desc\":\"bad request: add_hostfwd: "
214213
"bad arguments.guest_addr\"}}";
215214
wrc = write(fd, err, strlen(err));
@@ -270,6 +269,7 @@ static void api_handle_req_list_hostfwd_foreach(gpointer data,
270269
JSON_Value *entry_value = json_value_init_object();
271270
JSON_Object *entry_object = json_value_get_object(entry_value);
272271
char host_addr[INET_ADDRSTRLEN], guest_addr[INET_ADDRSTRLEN];
272+
char host_addr6[INET6_ADDRSTRLEN], guest_addr6[INET6_ADDRSTRLEN];
273273
if (inet_ntop(AF_INET, &fwd->host_addr, host_addr, sizeof(host_addr)) ==
274274
NULL) {
275275
perror("fatal: inet_ntop");
@@ -280,11 +280,29 @@ static void api_handle_req_list_hostfwd_foreach(gpointer data,
280280
perror("fatal: inet_ntop");
281281
exit(EXIT_FAILURE);
282282
}
283+
if (fwd->is_ipv6) {
284+
if (inet_ntop(AF_INET6, &fwd->host_addr6, host_addr6, sizeof(host_addr6)) ==
285+
NULL) {
286+
perror("fatal: inet_ntop");
287+
exit(EXIT_FAILURE);
288+
}
289+
if (inet_ntop(AF_INET6, &fwd->guest_addr6, guest_addr6, sizeof(guest_addr6)) ==
290+
NULL) {
291+
perror("fatal: inet_ntop");
292+
exit(EXIT_FAILURE);
293+
}
294+
}
283295
json_object_set_number(entry_object, "id", fwd->id);
284296
json_object_set_string(entry_object, "proto", fwd->is_udp ? "udp" : "tcp");
285297
json_object_set_string(entry_object, "host_addr", host_addr);
298+
if (fwd->is_ipv6) {
299+
json_object_set_string(entry_object, "host_addr6", host_addr6);
300+
}
286301
json_object_set_number(entry_object, "host_port", fwd->host_port);
287302
json_object_set_string(entry_object, "guest_addr", guest_addr);
303+
if (fwd->is_ipv6) {
304+
json_object_set_string(entry_object, "guest_addr6", guest_addr6);
305+
}
288306
json_object_set_number(entry_object, "guest_port", fwd->guest_port);
289307
/* json_array_append_value does not copy passed value */
290308
if (json_array_append_value(entries_array, entry_value) != JSONSuccess) {

‎main.c

+39-11
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,9 @@ static void usage(const char *argv0)
524524
printf(
525525
"--cidr=CIDR specify network address CIDR (default=%s)\n",
526526
DEFAULT_CIDR);
527+
printf(
528+
"--cidr6=CIDR specify network address CIDR (default=%s)\n",
529+
DEFAULT_CIDR6);
527530
printf("--disable-host-loopback prohibit connecting to 127.0.0.1:* on the "
528531
"host namespace\n");
529532
/* v0.4.0 */
@@ -611,6 +614,10 @@ static void options_destroy(struct options *options)
611614
free(options->cidr);
612615
options->cidr = NULL;
613616
}
617+
if (options->cidr6 != NULL) {
618+
free(options->cidr6);
619+
options->cidr6 = NULL;
620+
}
614621
if (options->api_socket != NULL) {
615622
free(options->api_socket);
616623
options->api_socket = NULL;
@@ -649,13 +656,15 @@ static void parse_args(int argc, char *const argv[], struct options *options)
649656
int opt;
650657
char *strtol_e = NULL;
651658
char *optarg_cidr = NULL;
659+
char *optarg_cidr6 = NULL;
652660
char *optarg_netns_type = NULL;
653661
char *optarg_userns_path = NULL;
654662
char *optarg_api_socket = NULL;
655663
char *optarg_outbound_addr = NULL;
656664
char *optarg_outbound_addr6 = NULL;
657665
char *optarg_macaddress = NULL;
658-
#define CIDR -42
666+
#define CIDR -41
667+
#define CIDR6 -42
659668
#define DISABLE_HOST_LOOPBACK -43
660669
#define NETNS_TYPE -44
661670
#define USERNS_PATH -45
@@ -675,6 +684,7 @@ static void parse_args(int argc, char *const argv[], struct options *options)
675684
{ "ready-fd", required_argument, NULL, 'r' },
676685
{ "mtu", required_argument, NULL, 'm' },
677686
{ "cidr", required_argument, NULL, CIDR },
687+
{ "cidr6", required_argument, NULL, CIDR6 },
678688
{ "disable-host-loopback", no_argument, NULL, DISABLE_HOST_LOOPBACK },
679689
{ "no-host-loopback", no_argument, NULL, _DEPRECATED_NO_HOST_LOOPBACK },
680690
{ "netns-type", required_argument, NULL, NETNS_TYPE },
@@ -728,6 +738,9 @@ static void parse_args(int argc, char *const argv[], struct options *options)
728738
case CIDR:
729739
optarg_cidr = optarg;
730740
break;
741+
case CIDR6:
742+
optarg_cidr6 = optarg;
743+
break;
731744
case _DEPRECATED_NO_HOST_LOOPBACK:
732745
// There was no tagged release with support for --no-host-loopback.
733746
// So no one will be affected by removal of --no-host-loopback.
@@ -800,6 +813,9 @@ static void parse_args(int argc, char *const argv[], struct options *options)
800813
if (optarg_cidr != NULL) {
801814
options->cidr = strdup(optarg_cidr);
802815
}
816+
if (optarg_cidr6 != NULL) {
817+
options->cidr6 = strdup(optarg_cidr6);
818+
}
803819
if (optarg_netns_type != NULL) {
804820
options->netns_type = strdup(optarg_netns_type);
805821
}
@@ -825,6 +841,7 @@ static void parse_args(int argc, char *const argv[], struct options *options)
825841
}
826842
}
827843
#undef CIDR
844+
#undef CIDR6
828845
#undef DISABLE_HOST_LOOPBACK
829846
#undef NETNS_TYPE
830847
#undef USERNS_PATH
@@ -940,10 +957,12 @@ static int parse_cidr6(struct in6_addr *network, struct in6_addr *netmask,
940957
{
941958
int rc = 0;
942959
regex_t r;
943-
regmatch_t matches[4];
960+
regmatch_t matches[5];
944961
size_t nmatch = sizeof(matches) / sizeof(matches[0]);
945-
const char *cidr_regex = "^(([a-fA-F0-9]{1,4}):){1,4}:/([0-9]{1,3})";
946-
char snetwork[INET6_ADDRSTRLEN], sprefix[INET6_ADDRSTRLEN];
962+
const char *cidr_regex = "^((([a-fA-F0-9]{1,4}):){1,4}):/([0-9]{1,3})";
963+
char snetwork[INET6_ADDRSTRLEN],
964+
snetwork_end[INET6_ADDRSTRLEN],
965+
sprefix[INET6_ADDRSTRLEN];
947966
int prefix;
948967
const char *random;
949968
rc = regcomp(&r, cidr_regex, REG_EXTENDED);
@@ -963,19 +982,28 @@ static int parse_cidr6(struct in6_addr *network, struct in6_addr *netmask,
963982
fprintf(stderr, "invalid CIDR: %s\n", cidr);
964983
goto finish;
965984
}
966-
rc = from_regmatch(sprefix, sizeof(sprefix), matches[3], cidr);
985+
rc = from_regmatch(snetwork_end, sizeof(snetwork_end), matches[2], cidr);
967986
if (rc < 0) {
968987
fprintf(stderr, "invalid CIDR: %s\n", cidr);
969988
goto finish;
970989
}
971-
random = pseudo_random_global_id(NULL);
972-
if (random == NULL) {
973-
fprintf(stderr, "cannot create pseudo random global id\n");
974-
rc = -1;
990+
rc = from_regmatch(sprefix, sizeof(sprefix), matches[4], cidr);
991+
if (rc < 0) {
992+
fprintf(stderr, "invalid CIDR: %s\n", cidr);
975993
goto finish;
976994
}
977-
strcpy(snetwork, random);
978-
strcat(snetwork, "0");
995+
if (strcmp(snetwork, snetwork_end) == 0) {
996+
random = pseudo_random_global_id(NULL);
997+
if (random == NULL) {
998+
fprintf(stderr, "cannot create pseudo random global id\n");
999+
rc = -1;
1000+
goto finish;
1001+
}
1002+
strcpy(snetwork, random);
1003+
strcat(snetwork, "0");
1004+
} else {
1005+
strcat(snetwork, ":0");
1006+
}
9791007

9801008
if (inet_pton(AF_INET6, snetwork, network) != 1) {
9811009
fprintf(stderr, "invalid network address: %s\n", snetwork);

‎tests/test-slirp4netns-api-socket.sh

+7-6
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,20 @@ result=$(cat /dev/zero | ncat -U $apisocket || true)
4747
set set -e
4848
echo $result | jq .error.desc | grep "bad request: too large message"
4949

50+
set -e
5051
result=$(echo '{"execute": "add_hostfwd", "arguments":{"proto": "tcp","host_port":8080,"guest_port":80}}' | ncat -U $apisocket)
5152
[[ $(echo $result | jq .error) == null ]]
5253
id=$(echo $result | jq .return.id)
5354
[[ $id == 1 ]]
5455

5556
result=$(echo '{"execute": "list_hostfwd"}' | ncat -U $apisocket)
5657
[[ $(echo $result | jq .error) == null ]]
57-
[[ $(echo $result | jq .return.entries[0].id) == $id ]]
58-
[[ $(echo $result | jq .return.entries[0].proto) == '"tcp"' ]]
59-
[[ $(echo $result | jq .return.entries[0].host_addr) == '"0.0.0.0"' ]]
60-
[[ $(echo $result | jq .return.entries[0].host_port) == 8080 ]]
61-
[[ $(echo $result | jq .return.entries[0].guest_addr) == '"10.0.2.100"' ]]
62-
[[ $(echo $result | jq .return.entries[0].guest_port) == 80 ]]
58+
[[ $(echo $result | jq .entries[0].id) == $id ]]
59+
[[ $(echo $result | jq .entries[0].proto) == '"tcp"' ]]
60+
[[ $(echo $result | jq .entries[0].host_addr) == '"0.0.0.0"' ]]
61+
[[ $(echo $result | jq .entries[0].host_port) == 8080 ]]
62+
[[ $(echo $result | jq .entries[0].guest_addr) == '"10.0.2.100"' ]]
63+
[[ $(echo $result | jq .entries[0].guest_port) == 80 ]]
6364

6465
result=$(echo '{"execute": "remove_hostfwd", "arguments":{"id": 1}}' | ncat -U $apisocket)
6566
[[ $(echo $result | jq .error) == null ]]

‎tests/test-slirp4netns-ipv6.sh

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/bash
2+
set -xeuo pipefail
3+
4+
. $(dirname $0)/common.sh
5+
6+
unshare -r -n sleep infinity &
7+
child=$!
8+
9+
wait_for_network_namespace $child
10+
11+
tmpdir=$(mktemp -d /tmp/slirp4netns-bench.XXXXXXXXXX)
12+
apisocket=${tmpdir}/slirp4netns.sock
13+
14+
slirp4netns -c $child --enable-ipv6 --cidr6=fd00:fb14:63ee:b::/64 --api-socket $apisocket tun11 &
15+
slirp_pid=$!
16+
17+
wait_for_network_device $child tun11
18+
19+
function cleanup() {
20+
kill -9 $child $slirp_pid
21+
rm -rf $tmpdir
22+
}
23+
trap cleanup EXIT
24+
25+
set +e
26+
result=$(cat /dev/zero | ncat -U $apisocket || true)
27+
set set -e
28+
echo $result | jq .error.desc | grep "bad request: too large message"
29+
30+
set -e
31+
result=$(echo '{"execute": "add_hostfwd", "arguments":{"proto": "tcp","host_port":8080,"guest_port":80}}' | ncat -U $apisocket)
32+
[[ $(echo $result | jq .error) == null ]]
33+
id=$(echo $result | jq .return.id)
34+
[[ $id == 1 ]]
35+
36+
result=$(echo '{"execute": "list_hostfwd"}' | ncat -U $apisocket)
37+
[[ $(echo $result | jq .error) == null ]]
38+
[[ $(echo $result | jq .entries[0].id) == $id ]]
39+
[[ $(echo $result | jq .entries[0].proto) == '"tcp"' ]]
40+
[[ $(echo $result | jq .entries[0].host_addr) == '"0.0.0.0"' ]]
41+
[[ $(echo $result | jq .entries[0].host_addr6) == '"::"' ]]
42+
[[ $(echo $result | jq .entries[0].host_port) == 8080 ]]
43+
[[ $(echo $result | jq .entries[0].guest_addr) == '"10.0.2.100"' ]]
44+
[[ $(echo $result | jq .entries[0].guest_addr6) == '"fd00:fb14:63ee:b::100"' ]]
45+
[[ $(echo $result | jq .entries[0].guest_port) == 80 ]]
46+
47+
result=$(echo '{"execute": "remove_hostfwd", "arguments":{"id": 1}}' | ncat -U $apisocket)
48+
[[ $(echo $result | jq .error) == null ]]
49+
50+
# see also: benchmarks/benchmark-iperf3-reverse.sh

0 commit comments

Comments
 (0)
Please sign in to comment.