~sircmpwn/hare-dev

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
7 4

[PATCH hare] net::dial: Fix address parsing

Details
Message ID
<6d42851189c1b204e10ebe7c530aba71d595bd90.1676478365.git.lassi@pulk.fi>
DKIM signature
missing
Download raw message
Patch: +24 -33
Allow IPv6 without port
Allow service name in address string

Signed-off-by: Lassi Pulkkinen <lassi@pulk.fi>
---
 net/dial/resolve.ha | 57 +++++++++++++++++++--------------------------
 1 file changed, 24 insertions(+), 33 deletions(-)

diff --git a/net/dial/resolve.ha b/net/dial/resolve.ha
index 9fa4e799..9361f5dc 100644
--- a/net/dial/resolve.ha
+++ b/net/dial/resolve.ha
@@ -18,60 +18,51 @@ export fn resolve(
	addr: str,
	service: str,
) (([]ip::addr, u16) | error) = {
	let port = if (strings::hasprefix(addr, '[')) {
		// [::1]:80
		yield match (strings::index(addr, "]:")) {
	if (strings::hasprefix(addr, '[')) {
		match (strings::index(addr, "]")) {
		case let i: size =>
			const sub = strings::sub(addr, i + 2, strings::end);
			const sub = strings::sub(addr, i + 1, strings::end);
			addr = strings::sub(addr, 1, i);
			yield match (strconv::stou16(sub)) {
			case let u: u16 =>
				yield u;
			case =>
			// [::1]
			if (len(sub) == 0) yield;
			// [::1]:80
			if (!strings::hasprefix(sub, ":")) {
				return invalid_address;
			};
			service = strings::sub(sub, 1, strings::end);
		case void =>
			return invalid_address;
		};
	} else {
		yield match (strings::index(addr, ':')) {
		case void =>
			yield match (strconv::stou16(service)) {
			case let u: u16 =>
				yield u;
			case =>
				yield 0u16;
			};
		match (strings::index(addr, ':')) {
		case let i: size =>
			const sub = strings::sub(addr, i + 1, strings::end);
			service = strings::sub(addr, i + 1, strings::end);
			addr = strings::sub(addr, 0, i);
			yield match (strconv::stou16(sub)) {
			case let u: u16 =>
				yield u;
			case =>
				return invalid_address;
			};
		case void => void;
		};
	};

	if (service == "unknown" && port == 0) {
		return unknown_service;
	const port = match (strconv::stou16(service)) {
	case let p: u16 =>
		yield p;
	case =>
		if (service == "unknown") {
			return unknown_service;
		};
		yield match (lookup_service(proto, service)) {
		case let p: u16 =>
			yield p;
		case void =>
			return unknown_service;
		};
	};

	let addrs = resolve_addr(addr)?;
	if (port == 0) match (lookup_service(proto, service)) {
	case let p: u16 =>
		port = p;
	case void => void;
	};

	// TODO:
	// - Consult /etc/services
	// - Fetch the SRV record

	if (port == 0) {
		return unknown_service;
	};
	if (len(addrs) == 0) {
		return dns::name_error;
	};
-- 
2.39.1

[hare/patches] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CQJA1DLH4V78.1JEPDBVC45CD3@cirno2>
In-Reply-To
<6d42851189c1b204e10ebe7c530aba71d595bd90.1676478365.git.lassi@pulk.fi> (view parent)
DKIM signature
missing
Download raw message
hare/patches: SUCCESS in 1m43s

[net::dial: Fix address parsing][0] from [Lassi Pulkkinen][1]

[0]: https://lists.sr.ht/~sircmpwn/hare-dev/patches/39029
[1]: lassi@pulk.fi

✓ #941031 SUCCESS hare/patches/alpine.yml  https://builds.sr.ht/~sircmpwn/job/941031
✓ #941032 SUCCESS hare/patches/freebsd.yml https://builds.sr.ht/~sircmpwn/job/941032
Details
Message ID
<CQJCI2D26XYO.26CY715PRCUSI@debian>
In-Reply-To
<6d42851189c1b204e10ebe7c530aba71d595bd90.1676478365.git.lassi@pulk.fi> (view parent)
DKIM signature
missing
Download raw message
On Wed Feb 15, 2023 at 10:26 AM CST, Lassi Pulkkinen wrote:

> Allow IPv6 without port
> Allow service name in address string

Is this really required?  Now the `service` parameter is redundant.

In any case, none of the expectations of a valid address string format
(whether it is hostname/IPv4/IPv6; has port/service) nor which
service/port has priority is documented.  All this should be documented
so that they aren't just implementation details.

>
> Signed-off-by: Lassi Pulkkinen <lassi@pulk.fi>
> ---
>  net/dial/resolve.ha | 57 +++++++++++++++++++--------------------------
>  1 file changed, 24 insertions(+), 33 deletions(-)
>
> diff --git a/net/dial/resolve.ha b/net/dial/resolve.ha
> index 9fa4e799..9361f5dc 100644
> --- a/net/dial/resolve.ha
> +++ b/net/dial/resolve.ha
> @@ -18,60 +18,51 @@ export fn resolve(
>  	addr: str,
>  	service: str,
>  ) (([]ip::addr, u16) | error) = {
> -	let port = if (strings::hasprefix(addr, '[')) {
> -		// [::1]:80
> -		yield match (strings::index(addr, "]:")) {
> +	if (strings::hasprefix(addr, '[')) {
> +		match (strings::index(addr, "]")) {
>  		case let i: size =>
> -			const sub = strings::sub(addr, i + 2, strings::end);
> +			const sub = strings::sub(addr, i + 1, strings::end);
>  			addr = strings::sub(addr, 1, i);
> -			yield match (strconv::stou16(sub)) {
> -			case let u: u16 =>
> -				yield u;
> -			case =>
> +			// [::1]
> +			if (len(sub) == 0) yield;
> +			// [::1]:80
> +			if (!strings::hasprefix(sub, ":")) {
>  				return invalid_address;
>  			};
> +			service = strings::sub(sub, 1, strings::end);

Shouldn't `service` parameter have priority over what comes with the
address?

>  		case void =>
>  			return invalid_address;
>  		};
>  	} else {
> -		yield match (strings::index(addr, ':')) {
> -		case void =>
> -			yield match (strconv::stou16(service)) {
> -			case let u: u16 =>
> -				yield u;
> -			case =>
> -				yield 0u16;
> -			};
> +		match (strings::index(addr, ':')) {
>  		case let i: size =>
> -			const sub = strings::sub(addr, i + 1, strings::end);
> +			service = strings::sub(addr, i + 1, strings::end);
>  			addr = strings::sub(addr, 0, i);
> -			yield match (strconv::stou16(sub)) {
> -			case let u: u16 =>
> -				yield u;
> -			case =>
> -				return invalid_address;
> -			};
> +		case void => void;
>  		};
>  	};
>  
> -	if (service == "unknown" && port == 0) {
> -		return unknown_service;
> +	const port = match (strconv::stou16(service)) {
> +	case let p: u16 =>
> +		yield p;
> +	case =>
> +		if (service == "unknown") {
> +			return unknown_service;
> +		};
> +		yield match (lookup_service(proto, service)) {
> +		case let p: u16 =>
> +			yield p;
> +		case void =>
> +			return unknown_service;
> +		};
>  	};
>  
>  	let addrs = resolve_addr(addr)?;
> -	if (port == 0) match (lookup_service(proto, service)) {
> -	case let p: u16 =>
> -		port = p;
> -	case void => void;
> -	};
>  
>  	// TODO:
>  	// - Consult /etc/services
>  	// - Fetch the SRV record
>  
> -	if (port == 0) {
> -		return unknown_service;
> -	};
>  	if (len(addrs) == 0) {
>  		return dns::name_error;
>  	};
> -- 
> 2.39.1




--
Details
Message ID
<20230215214520.51DE81FB03@pulk.fi>
In-Reply-To
<CQJCI2D26XYO.26CY715PRCUSI@debian> (view parent)
DKIM signature
missing
Download raw message
> Now the `service` parameter is redundant.

No it isn't. It's used to provide a default, whereas `addr` would
typically be user-provided.

> In any case, none of the expectations of a valid address string format
> (whether it is hostname/IPv4/IPv6; has port/service) nor which
> service/port has priority is documented.  All this should be documented
> so that they aren't just implementation details.

This is documented on the `dial` function; that should indeed be
updated to reflect these changes. (Conspicuously, it leaves the
port-less case of IPv6 addresses unmentioned.)

> Shouldn't `service` parameter have priority over what comes with the
> address?

As I already implied, no, nor did it ever work this way. This is also
documented on `dial`.
Details
Message ID
<20230215221639.2D9871FB03@pulk.fi>
In-Reply-To
<20230215214520.51DE81FB03@pulk.fi> (view parent)
DKIM signature
missing
Download raw message
Slight correction: the service parameter is also meant to be used for
SRV resolution, which I forgot about because it hasn't been implemented
yet. A service name provided in the address probably shouldn't affect
that, making the case for allowing it a bit questionable. Up to the
maintainers, I guess.
Details
Message ID
<CQJHPAT3SLWH.3KT4T4LIUDPT4@debian>
In-Reply-To
<20230215214520.51DE81FB03@pulk.fi> (view parent)
DKIM signature
missing
Download raw message
On Wed Feb 15, 2023 at 3:45 PM CST, Lassi Pulkkinen wrote:

> > Now the `service` parameter is redundant.
>
> No it isn't. It's used to provide a default, whereas `addr` would
> typically be user-provided.
>
> > In any case, none of the expectations of a valid address string format
> > (whether it is hostname/IPv4/IPv6; has port/service) nor which
> > service/port has priority is documented.  All this should be documented
> > so that they aren't just implementation details.
>
> This is documented on the `dial` function; that should indeed be
> updated to reflect these changes. (Conspicuously, it leaves the
> port-less case of IPv6 addresses unmentioned.)

Oh, I see.  Then net::dial:dial should be referenced in the
documentation.  net::dial::resolve is a public, standalone function, it
should be properly documented.

>
> > Shouldn't `service` parameter have priority over what comes with the
> > address?
>
> As I already implied, no, nor did it ever work this way. This is also
> documented on `dial`.
Details
Message ID
<20230216132421.1C2321FAFB@pulk.fi>
In-Reply-To
<CQJHPAT3SLWH.3KT4T4LIUDPT4@debian> (view parent)
DKIM signature
missing
Download raw message
> Oh, I see.  Then net::dial:dial should be referenced in the
> documentation.  net::dial::resolve is a public, standalone function, it
> should be properly documented.

Agreed. I'll wait for code review before updating the docs.
Details
Message ID
<CS0MHSZWHVZW.1TOIJFZI5CTN5@taiga>
In-Reply-To
<6d42851189c1b204e10ebe7c530aba71d595bd90.1676478365.git.lassi@pulk.fi> (view parent)
DKIM signature
missing
Download raw message
On Wed Feb 15, 2023 at 5:26 PM CET, Lassi Pulkkinen wrote:
> Allow IPv6 without port

ACK

> Allow service name in address string

NACK
Reply to thread Export thread (mbox)