POC of gomobile
parent
813ca8adea
commit
860a487ac8
@ -0,0 +1,4 @@
|
||||
# Replace JAVA_HOME with the right path for your environment
|
||||
|
||||
libtailscale.aar: *.go go.mod go.sum
|
||||
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home gomobile bind -target android -androidapi 21 libtailscale
|
@ -0,0 +1,5 @@
|
||||
module libtailscale
|
||||
|
||||
go 1.21.5
|
||||
|
||||
require golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b // indirect
|
@ -0,0 +1,2 @@
|
||||
golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b h1:kfWLZgb8iUBHdE9WydD5V5dHIS/F6HjlBZNyJfn2bs4=
|
||||
golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b/go.mod h1:4efzQnuA1nICq6h4kmZRMGzbPiP06lZvgADUu1VpJCE=
|
@ -0,0 +1,130 @@
|
||||
package libtailscale
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/ipn/localapi"
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/netmon"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/tsd"
|
||||
"tailscale.com/types/logid"
|
||||
"tailscale.com/wgengine"
|
||||
"tailscale.com/wgengine/router"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
Method string
|
||||
Path string
|
||||
Headers map[string][]string
|
||||
Body []byte
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
StatusCode int
|
||||
Headers map[string][]string
|
||||
bodyWriter *bytes.Buffer
|
||||
}
|
||||
|
||||
func (resp *Response) Body() []byte {
|
||||
return resp.bodyWriter.Bytes()
|
||||
}
|
||||
|
||||
type Tailscale interface {
|
||||
ProcessRequest(req *Request) *Response
|
||||
}
|
||||
|
||||
type tailscale struct {
|
||||
backend *ipnlocal.LocalBackend
|
||||
localapi *localapi.Handler
|
||||
}
|
||||
|
||||
func NewTailscale() (Tailscale, error) {
|
||||
logf := log.Printf
|
||||
var sys tsd.System
|
||||
var logID logid.PrivateID
|
||||
logID.UnmarshalText([]byte("dead0000dead0000dead0000dead0000dead0000dead0000dead0000dead0000"))
|
||||
netMon, err := netmon.New(logf)
|
||||
if err != nil {
|
||||
log.Printf("netmon.New: %w", err)
|
||||
}
|
||||
dialer := new(tsdial.Dialer)
|
||||
cb := &router.CallbackRouter{
|
||||
SetBoth: func(rcfg *router.Config, dcfg *dns.OSConfig) error { return nil },
|
||||
SplitDNS: false,
|
||||
GetBaseConfigFunc: nil,
|
||||
}
|
||||
engine, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{
|
||||
Tun: nil,
|
||||
Router: cb,
|
||||
DNS: cb,
|
||||
Dialer: dialer,
|
||||
SetSubsystem: sys.Set,
|
||||
NetMon: netMon,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("runBackend: NewUserspaceEngine: %v", err)
|
||||
}
|
||||
sys.Set(engine)
|
||||
backend, err := ipnlocal.NewLocalBackend(logf, logID.Public(), &sys, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api := localapi.NewHandler(backend, logf, netMon, logID.Public())
|
||||
return &tailscale{
|
||||
backend: backend,
|
||||
localapi: api,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *tailscale) ProcessRequest(req *Request) (resp *Response) {
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
resp = &Response{
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
}
|
||||
fmt.Fprintf(resp, "%s", p)
|
||||
}
|
||||
}()
|
||||
|
||||
resp = &Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Headers: make(map[string][]string),
|
||||
bodyWriter: &bytes.Buffer{},
|
||||
}
|
||||
t.localapi.ServeHTTP(resp, req.AsHTTPRequest())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (req *Request) AsHTTPRequest() *http.Request {
|
||||
result, _ := http.NewRequest(req.Method, fmt.Sprintf("http://server/%v", req.Path), nil)
|
||||
if req.Body != nil {
|
||||
result.Body = io.NopCloser(bytes.NewReader(req.Body))
|
||||
}
|
||||
if req.Headers != nil {
|
||||
for name, values := range req.Headers {
|
||||
for _, value := range values {
|
||||
result.Header.Add(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (resp *Response) Header() http.Header {
|
||||
return http.Header(resp.Headers)
|
||||
}
|
||||
|
||||
func (resp *Response) WriteHeader(statusCode int) {
|
||||
resp.StatusCode = statusCode
|
||||
}
|
||||
|
||||
func (resp *Response) Write(p []byte) (int, error) {
|
||||
return resp.bodyWriter.Write(p)
|
||||
}
|
Loading…
Reference in New Issue