diff --git a/conf.c b/conf.c index 5e15b66..f68f5d3 100644 --- a/conf.c +++ b/conf.c @@ -119,6 +119,7 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, bool exclude_only = true, bound_one = false; uint8_t exclude[PORT_BITMAP_SIZE] = { 0 }; sa_family_t af = AF_UNSPEC; + unsigned i; int ret; if (!strcmp(optarg, "none")) { @@ -141,8 +142,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, } if (!strcmp(optarg, "all")) { - unsigned i; - if (fwd->mode) goto mode_conflict; @@ -171,7 +170,7 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, } if (!bound_one) - goto bind_fail; + goto bind_all_fail; return; } @@ -221,7 +220,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, p = spec; do { struct port_range xrange; - unsigned i; if (*p != '~') { /* Not an exclude range, parse later */ @@ -244,8 +242,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, } while ((p = next_chunk(p, ','))); if (exclude_only) { - unsigned i; - for (i = 0; i < PORT_EPHEMERAL_MIN; i++) { if (bitmap_isset(exclude, i)) continue; @@ -271,7 +267,7 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, } if (!bound_one) - goto bind_fail; + goto bind_all_fail; return; } @@ -280,7 +276,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, p = spec; do { struct port_range orig_range, mapped_range; - unsigned i; if (*p == '~') /* Exclude range, already parsed */ @@ -314,28 +309,16 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, fwd->delta[i] = mapped_range.first - orig_range.first; - if (optname == 't') { + ret = 0; + if (optname == 't') ret = tcp_sock_init(c, af, addr, ifname, i); - if (ret == -ENFILE || ret == -EMFILE) - goto enfile; - if (!ret) - bound_one = true; - } else if (optname == 'u') { + else if (optname == 'u') ret = udp_sock_init(c, 0, af, addr, ifname, i); - if (ret == -ENFILE || ret == -EMFILE) - goto enfile; - if (!ret) - bound_one = true; - } else { - /* No way to check in advance for -T and -U */ - bound_one = true; - } + if (ret) + goto bind_fail; } } while ((p = next_chunk(p, ','))); - if (!bound_one) - goto bind_fail; - return; enfile: die("Can't open enough sockets for port specifier: %s", optarg); @@ -344,6 +327,9 @@ bad: mode_conflict: die("Port forwarding mode '%s' conflicts with previous mode", optarg); bind_fail: + die("Failed to bind port %u (%s) for option '-%c %s', exiting", + i, strerror(-ret), optname, optarg); +bind_all_fail: die("Failed to bind any port for '-%c %s', exiting", optname, optarg); } diff --git a/passt.1 b/passt.1 index cc678ed..dc2d719 100644 --- a/passt.1 +++ b/passt.1 @@ -355,7 +355,8 @@ Don't forward any ports .TP .BR all Forward all unbound, non-ephemeral ports, as permitted by current capabilities. -For low (< 1024) ports, see \fBNOTES\fR. +For low (< 1024) ports, see \fBNOTES\fR. No failures are reported for +unavailable ports, unless no ports could be forwarded at all. .TP .BR ports @@ -364,7 +365,11 @@ optionally, with target ports after \fI:\fR, if they differ. Specific addresses can be bound as well, separated by \fI/\fR, and also, since Linux 5.7, limited to specific interfaces, prefixed by \fI%\fR. Within given ranges, selected ports and ranges can be excluded by an additional specification prefixed by \fI~\fR. -Specifying excluded ranges only implies that all other ports are forwarded. + +Specifying excluded ranges only implies that all other ports are forwarded. In +this case, no failures are reported for unavailable ports, unless no ports could +be forwarded at all. + Examples: .RS .TP @@ -447,7 +452,11 @@ optionally, with target ports after \fI:\fR, if they differ. Specific addresses can be bound as well, separated by \fI/\fR, and also, since Linux 5.7, limited to specific interfaces, prefixed by \fI%\fR. Within given ranges, selected ports and ranges can be excluded by an additional specification prefixed by \fI~\fR. -Specifying excluded ranges only implies that all other ports are forwarded. + +Specifying excluded ranges only implies that all other ports are forwarded. In +this case, no failures are reported for unavailable ports, unless no ports could +be forwarded at all. + Examples: .RS .TP