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

Forced IPv6 on arm? #5

Closed
xDavo opened this issue Nov 10, 2019 · 10 comments
Closed

Forced IPv6 on arm? #5

xDavo opened this issue Nov 10, 2019 · 10 comments

Comments

@xDavo
Copy link

xDavo commented Nov 10, 2019

Hi,

first thank you for your app! This is exactly what I need to compliment my use of Standard Notes on Android :)

My usecase is to be able to insert new note directly from homescreen using Termux (https://github.com/termux/termux-app) and Tasker - and thus avoiding having to open the app, wait for the decrypt and then pressing the plus button.
I tested this on linux desktop and all was great. But once I run the arm64 version in termux on android I cannot connect to the server. It seems like it forces IPv6 - which is not setup on our selfhosted instance.

Here's the log:

Get https://redacted-address/auth/params?email=redacted-username: dial tcp: lookup redacted-address on [::1]:53: read udp [::1]:40903->[::1]:53: read: connection refused

Is there a way I can force it to use normal IPv4 address which I'm able to ping as well as use via standard Standard Notes app?
I've tested Termux v0.77 on both Android 7 and Android 9.

It is possible that I'm looking in a wrong direction or even stretching your app way beyond it's limits. I'll be happy if you can let me know :)

@jonhadfield
Copy link
Owner

jonhadfield commented Nov 10, 2019

Hi, thanks for the feedback.
The error is when it's trying to resolve the name (the redacted-address bit) before it can make the request. This is done using go's native library and I don't think I have the ability to override it's selection of ipv4/ipv6.
The log message says it's trying to lookup the name using a name server running locally which seems odd.
I'll try and debug. In the meantime, would it be possible to put the IP address and name of your server in the hosts (/etc/hosts) file as that should be interrogated before querying a name server?

@xDavo
Copy link
Author

xDavo commented Nov 11, 2019

Hello @jonhadfield,

thank you for your quick answer. Regarding the go's native library I assumed as much.
I have installed dnsutils and nslookup is returning that DNS in use is 8.8.8.8 (Google).

The hosts idea has occured to me too already before but apparently I made a mistake. Now I have corrected it and seems like it did the trick :)

To be completely honest this is a solution that is satisfactory to me. So if you wish to close the ticket I'm not going to be against it :)

@jonhadfield
Copy link
Owner

I've got a raspberry pi (running linux on arm64) running so I can do some tests.
Assume ipv6 is enabled in the kernel on your instance or go wouldn't attempt to use it for lookups. It might be the only lookup options on your instance (that go's dns lib can see) are: hosts file and local resolver [::1]:53: that it fails to connect to.
I don't think it's anything in my code as I'm not doing anything clever with name resolution but some testing should prove that.

@xDavo
Copy link
Author

xDavo commented Nov 11, 2019

That does sound like a reasonable explanation.

What I do not understand is IPv6 is preferred to such extent that IPv4 is completely ignored - as I said ping and nslookup worked perfectly fine.

There is very little chance I might have caused it in some way - but I spent good portion of yesterday trying to figure it out to no avail.

If you'd like I can perform more tests for you :)

@jonhadfield
Copy link
Owner

I agree. I've seen general behaviour in linux where ipv6 connections will be attempted before ipv4, but not exclusively so that they simply try and fail. I am intrigued now and will test on arm64 asap.

@jonhadfield
Copy link
Owner

Tested on Linux running arm64, with and without ipv6 enabled, and couldn't recreate the issue. I wish I could test on Android (as I think that's the next thing to rule out) but wouldn't know where to start.
Are you aware of any other apps written in go (that make remote requests) you could try? If not, I can write a tiny app that will simply do a lookup and return the IP. If that worked, I can then focus back on my app.

@xDavo
Copy link
Author

xDavo commented Nov 18, 2019

hi :) I have not managed to obtain an app that I could try out. I got a simple app (source code below) but it did not run in the android/termux environment. I don't know what was the culprit - we tried to compile for android (GOOS=android GOARCH=arm64) but that did not compile. So we compiled for linux, arm and arm64 but neither of them were possible to run.

So I kinda need you to quickly put together something simple so I can test that for you.

I'm not sure if that is any iteresting to you but here's the code of his app that I did not manage to run+error.

package main

import (
  "fmt"
  "io/ioutil"
  "net/http"
)

func main() {
  res, _ := http.Get("https://api.ipify.org")
  ip, _ := ioutil.ReadAll(res.Body)
  fmt.Println("IPv4: ", string(ip))

  res6, _ := http.Get("https://api6.ipify.org")
  ip6, _ := ioutil.ReadAll(res6.Body)
  fmt.Println("IPv6: ", string(ip6))
}

and here's the result

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x1f503c]

goroutine 1 [running]:
main.main()
/root/getIP/getIP.go:11 +0x4c

@jonhadfield
Copy link
Owner

jonhadfield commented Nov 18, 2019

Hi
My guess is that when it executes statement res, _ := http.Get("https://api.ipify.org") it is failing. You are ignoring the error response, so the next statement is trying to read from res, which is nil (due to the error).
Try replacing res, _ := http.Get("https://api.ipify.org") with res, err := http.Get("https://api.ipify.org") and add the following underneath that line:

if err != nil {  
    panic(err)
}

I'm guessing it will be a DNS (lookup) failure.

You could also try this which uses the native go library to do a simple lookup (the precursor to the http.Get in your first example):


import (
        "fmt"
        "net"
        "os"
)

func main() {
        ips, err := net.LookupIP("api.ipify.org")
        if err != nil {
                fmt.Fprintf(os.Stderr, "Could not get IPs: %v\n", err)
                os.Exit(1)
        }
        for _, ip := range ips {
                fmt.Printf("api.ipify.org. IN A %s\n", ip.String())
        }
}

@jonhadfield
Copy link
Owner

I've done some digging and it looks like a known problem with running go apps on Android:
golang/go#8877
https://www.sajalkayan.com/post/go-android-binary.html

The latter suggests using the following to compile using: https://godoc.org/golang.org/x/mobile/cmd/gomobile. I'll give it a go.

@xDavo
Copy link
Author

xDavo commented Nov 18, 2019

either way, your sncli is compiled for linux/arm, so it should not matter. after all the problem we are trying to debug here is the IPv6 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants