Segfault in FetchIPFromSTUNCall

To reproduce:

pea@peabox:bootstrap go test -count=1 -v ./... -run TestGeolocatation       
=== RUN   TestGeolocatation                                                    
9:31AM DBG Disabling DNS over HTTP (not using SSL)                             
9:31AM DBG Getting ip address                                                  
9:31AM WRN Could not get ip address with WebAPIs. Now trying STUN servers.     
9:31AM TRC Trying STUN server server=stun.syncthing.net:3478                   
WE HAVE AN ERROR                       
panic: runtime error: invalid memory address or nil pointer dereference                                                
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x83139a]        
                                       
goroutine 9 [running]:                 
github.com/pion/stun.(*Message).Get(...)                                                                               
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/attributes.go:223                                          
github.com/pion/stun.(*XORMappedAddress).GetFromAs(0xcc5760?, 0xc000134090?, 0x76d0?)                                  
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/xoraddr.go:88 +0x1a                                        
github.com/pion/stun.(*XORMappedAddress).GetFrom(...)                                                                  
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/xoraddr.go:149                                             
0xacab.org/leap/tunnel-telemetry/pkg/geolocate.FetchIPFromSTUNCall.func1({{0x73, 0xe4, 0x18, 0xab, 0xa9, 0xaf, 0x60, 0xc8, 0x16, 0x14, ...}, ...})
        /home/pea/projects/leap/tunnel-telemetry/pkg/geolocate/stun.go:63 +0xb7                                     
github.com/pion/stun.(*callbackWaitHandler).HandleEvent(0xc0003786c0, {{0x73, 0xe4, 0x18, 0xab, 0xa9, 0xaf, 0x60, 0xc8, 0x16, ...}, ...})
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/client.go:521 +0x5b                                        
github.com/pion/stun.(*clientTransaction).handle(...)                                                                  
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/client.go:309
github.com/pion/stun.(*Client).handleAgentCallback(0xc0003cfb80, {{0x73, 0xe4, 0x18, 0xab, 0xa9, 0xaf, 0x60, 0xc8, 0x16, ...}, ...})
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/client.go:629 +0x16e
github.com/pion/stun.(*Agent).Collect(0xc000378660, {0x0?, 0xc000077f20?, 0x1170580?})
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/agent.go:176 +0x3e6
github.com/pion/stun.NewClient.func1({0xc000077f98?, 0xc000077f78?, 0x1170580?})
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/client.go:230 +0x31                                        
github.com/pion/stun.(*tickerCollector).Start.func1()                          
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/client.go:455 +0x90   
created by github.com/pion/stun.(*tickerCollector).Start in goroutine 6        
        /home/pea/go/pkg/mod/github.com/pion/stun@v0.6.1/client.go:447 +0xa5
FAIL    0xacab.org/leap/bitmask-core/pkg/bootstrap      10.853s
FAIL                                   

TestGeolocatation is defined in bitmask-core:pkg/bootstrap/geolocate_test.go.

// FetchIPFromSTUNCall tries to get our public IP using the passed
// stun uri. It returns an error of the operation does not succeed.
func FetchIPFromSTUNCall(uri string) (string, error) {
    u, err := stun.ParseURI("stun:" + uri)
    if err != nil {
        return "", err 
    }   

    // Create a "connection" to STUN server.
    c, err := stun.DialURI(u, &stun.DialConfig{})
    if err != nil {
        return "", err 
    }   
    // Build binding request with random transaction id.
    message := stun.MustBuild(stun.TransactionID, stun.BindingRequest)

    errch, ipch := make(chan error, 1), make(chan string, 1)

    // Send request to STUN server, waiting for response message.
    if err := c.Do(message, func(res stun.Event) {
        if res.Error != nil {
            errch <- res.Error
        }   
        // Decode XOR-MAPPED-ADDRESS attribute from message.
        var xorAddr stun.XORMappedAddress
        if err := xorAddr.GetFrom(res.Message); err != nil {
            errch <- err 
        }   
        ipch <- xorAddr.IP.String()
    }); err != nil {
        return "", err 
    }   
    // TODO(ain): add timeout/ctx
    select {
    case err := <-errch:
        return "127.0.0.1", err 
    case ip := <-ipch:
        return ip, nil
    }
}

The problem: Sometimes we are in this code path:

if res.Error != nil {
    errch <- res.Error
}

But at this point we don't return. We need a break or an else at this point to not continue at this point.
I don't know why there are channels. We could just return an error and return from the function if an error happens. Don't know why it is that complicated.