Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Name resolution does not work without filesystem access #82

Open
KEANO89 opened this issue Jul 10, 2023 · 2 comments
Open

Name resolution does not work without filesystem access #82

KEANO89 opened this issue Jul 10, 2023 · 2 comments
Labels
enhancement New feature or request help wanted Extra attention is needed question Further information is requested

Comments

@KEANO89
Copy link

KEANO89 commented Jul 10, 2023

At the moment DNS lookups seem to require filesystem access. Is that intended behavior?

Steps to reproduce:

package main

import (
	"fmt"
	"log"
	"net"

	_ "github.com/stealthrocket/net/wasip1"
)

func main() {
	ips, err := net.LookupIP("example.org")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(ips)
}
❯ GOOS=wasip1 GOARCH=wasm gotip build -o dnstest.wasm dnstest.go
❯ gotip version
go version devel go1.21-5c15498 Fri Jul 7 22:02:26 2023 +0000 linux/amd64
❯ wasirun --version
wasirun v0.7.2

Result:

❯ wasirun --dir=/ dnstest.wasm
[2606:2800:220:1:248:1893:25c8:1946 93.184.216.34]
❯ wasirun --dns-server 9.9.9.9:53 dnstest.wasm
2023/07/10 08:37:11 lookup example.org on [::1]:53: Connection refused

Without docs saying otherwise I'd expect the last invocation to work as well

@achille-roussel
Copy link
Contributor

achille-roussel commented Jul 11, 2023

Thanks for reporting!

The --dns-server option configures the DNS server used when the guest module calls sock_getaddrinfo.

The guest program you use is compiled with Go 1.21 and https://github.com/stealthrocket/net, so by default, it will use the pure Go resolver as documented in https://github.com/stealthrocket/net#name-resolution; This means that the guest application opens a UDP socket and sends the queries to the DNS server it finds in /etc/resolv.conf, which is why the file system needs to be exposed.

I tried building your example with -tags=getaddrinfo but in this case you're using the Go resolver via net.LookupIP which still tries to connect to a DNS server on localhost:

SockAddressInfo(127.0.0.1, 53, {Flags:NumericHost|NumericService,Family:UnspecifiedFamily,SocketType:DatagramSocket,Protocol:UDPProtocol}, [8]AddressInfo) => [{Flags:NumericHost|NumericService,Family:InetFamily,SocketType:DatagramSocket,Protocol:UDPProtocol,Address:127.0.0.1:53}]
SockOpen(InetFamily, DatagramSocket, IPProtocol, SockConnectionRights|SockListenRights, SockConnectionRights) => 4
FDStatGet(4) => {FileType:SocketDGramType,RightsBase:SockConnectionRights|SockListenRights,RightsInheriting:SockConnectionRights}
FDStatSetFlags(4, NonBlock) => ok
SockSetOpt(4, Broadcast, 1) => ok
SockConnect(4, 127.0.0.1:53) => 127.0.0.1:60268
SockLocalAddress(4) => 127.0.0.1:60268
SockRemoteAddress(4) => 127.0.0.1:53
FDStatGet(4) => {FileType:SocketDGramType,Flags:NonBlock,RightsBase:SockConnectionRights|SockListenRights,RightsInheriting:SockConnectionRights}
ClockTimeGet(1, 0) => 185606458
ClockTimeGet(1, 0) => 185608583
FDWrite(4, [1]IOVec{[40]byte("8\x93\1\0\0\1\0\0\0\0\0\1\7example\3org\0\0\1\0\1\0\0)"...)}) => 40
SockRecvFrom(4, [1]IOVec{[1232]Byte}, RIFlags(0)) => ECONNREFUSED (Connection refused)

There is a hard dependency on /etc/resolv.conf that cannot be worked around here.

The "right way" to address this issue would probably be to modify wasi-go's unix system to support "mounting" /etc/resolv.conf to a virtual file generated to have the DNS server passed to --dns-server (pretty similar to what docker does). However, it might be a bit outside the scope of our goals for this project, we provide wasirun as a test utility for the wasi-go library; it's not intended to be used as a general-purpose production runtime.

If you can take on the work to implement such feature, we would happily review and commit to the long-term maintenance of the code 👍

@achille-roussel achille-roussel added enhancement New feature or request help wanted Extra attention is needed question Further information is requested labels Jul 11, 2023
@achille-roussel
Copy link
Contributor

@chriso pointed out that another option could be to add a lookup functions in the wasip1 package such as wasip1.LookupIP, which would bypass the Go resolver when building with -tags=getaddrinfo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants