From e85070a3fb601e1872d121ce3c1c9d39f8f41036 Mon Sep 17 00:00:00 2001 From: jwijenbergh Date: Wed, 23 Oct 2024 11:31:39 +0200 Subject: All: Refactor to latest ProxyGuard --- exports/exports.go | 82 +++++++++++++++++++++++++++++++++++++++--------------- exports/exports.h | 11 ++------ 2 files changed, 62 insertions(+), 31 deletions(-) (limited to 'exports') diff --git a/exports/exports.go b/exports/exports.go index 511a1f9..6df8c33 100644 --- a/exports/exports.go +++ b/exports/exports.go @@ -29,6 +29,7 @@ import ( "github.com/eduvpn/eduvpn-common/client" "github.com/eduvpn/eduvpn-common/i18nerr" "github.com/eduvpn/eduvpn-common/internal/log" + "github.com/eduvpn/eduvpn-common/proxy" "github.com/eduvpn/eduvpn-common/types/cookie" errtypes "github.com/eduvpn/eduvpn-common/types/error" srvtypes "github.com/eduvpn/eduvpn-common/types/server" @@ -876,50 +877,85 @@ func StartFailover(c C.uintptr_t, gateway *C.char, mtu C.int, readRxBytes C.Read return droppedC, nil } -// StartProxyguard starts the 'proxyguard' procedure in eduvpn-common. +// NewProxyguard creates the 'proxyguard' procedure in eduvpn-common. // eduvpn-common currently also cleans up the running ProxyGuard process in `cleanup`. -// If the proxy cannot be started it returns an error. +// If the proxy cannot be created it returns an error. // // This function proxies WireGuard UDP connections over HTTP: [ProxyGuard on Codeberg](https://codeberg.org/eduvpn/proxyguard). // // These input variables can be gotten from the configuration that is retrieved using the `proxy` JSON key // // - `c` is the cookie. Note that if you cancel/delete the cookie, ProxyGuard gets cleaned up. Common automatically cleans up ProxyGuard when `Cleanup` is called, but it is good to cleanup yourself too. -// - `listen` is the `ip:port` of the local udp connection, this is what is set to the WireGuard endpoint +// - `lp` is the `port` of the local udp ProxyGuard connection, this is what is set to the WireGuard endpoint // - `tcpsp` is the TCP source port. Pass 0 if you do not route based on source port, so far only the Linux client has to pass non-zero. // - `peer` is the `ip:port` of the remote server // - `proxySetup` is a callback which is called when the socket is setting up, this can be used for configuring routing in the client. It takes two arguments: the file descriptor (integer) and a JSON list of IPs the client connects to -// - `proxyReady` is a callback when the proxy is ready to be used. This is only called when the client is not connected yet. Use this to determine when the actual wireguard connection can be started. This callback returns and takes no arguments // -// Example Input: ```StartProxyGuard(myCookie, "127.0.0.1:1337", 0, "5.5.5.5:51820", proxySetupCB, proxyReadyCB)``` +// Example Input: ```StartProxyGuard(myCookie, 1337, 0, "5.5.5.5:51820", proxySetupCB)``` // // Example Output: ```null``` // -//export StartProxyguard -func StartProxyguard(c C.uintptr_t, listen *C.char, tcpsp C.int, peer *C.char, proxySetup C.ProxySetup, proxyReady C.ProxyReady) *C.char { - state, stateErr := getVPNState() - if stateErr != nil { - return getCError(stateErr) - } +//export NewProxyguard +func NewProxyguard(c C.uintptr_t, lp C.int, tcpsp C.int, peer *C.char, proxySetup C.ProxySetup) (C.uintptr_t, *C.char) { ck, err := getCookie(c) if err != nil { - return getCError(err) + return 0, getCError(err) } - - proxyErr := state.StartProxyguard(ck, C.GoString(listen), int(tcpsp), C.GoString(peer), func(fd int, pips string) { + proxy, proxyErr := proxy.NewProxyguard(ck.Context(), int(lp), int(tcpsp), C.GoString(peer), func(fd int) { if proxySetup == nil { return } - cpip := C.CString(pips) - C.call_proxy_setup(proxySetup, C.int(fd), cpip) - FreeString(cpip) - }, func() { - if proxyReady == nil { - return - } - C.call_proxy_ready(proxyReady) + C.call_proxy_setup(proxySetup, C.int(fd)) }) - return getCError(proxyErr) + if proxyErr != nil { + return 0, getCError(proxyErr) + } + return C.uintptr_t(cgo.NewHandle(proxy)), nil +} + +func getProxy(proxyH C.uintptr_t) (*proxy.Proxy, error) { + h := cgo.Handle(proxyH) + v, ok := h.Value().(*proxy.Proxy) + if !ok { + return nil, i18nerr.NewInternal("value is not a proxyguard wrapper") + } + return v, nil +} + +//export ProxyguardTunnel +func ProxyguardTunnel(c C.uintptr_t, proxyH C.uintptr_t, wglisten C.int) *C.char { + ck, err := getCookie(c) + if err != nil { + return getCError(err) + } + pr, err := getProxy(proxyH) + if err != nil { + return getCError(err) + } + tunnelErr := pr.Tunnel(ck.Context(), int(wglisten)) + + // after tunneling is done, the handle should be deleted + cgo.Handle(proxyH).Delete() + return getCError(tunnelErr) +} + +//export ProxyguardPeerIPs +func ProxyguardPeerIPs(proxyH C.uintptr_t) (*C.char, *C.char) { + pr, err := getProxy(proxyH) + if err != nil { + return nil, getCError(err) + } + pips := pr.PeerIPS + + b, err := json.Marshal(pips) + if err != nil { + return nil, getCError(i18nerr.WrapInternal(err, "failed converting Peer IPs to JSON")) + } + ret, err := getReturnData(string(b)) + if err != nil { + return nil, getCError(err) + } + return C.CString(ret), nil } // SetState sets the state of the state machine. diff --git a/exports/exports.h b/exports/exports.h index a31920b..9ec39e4 100644 --- a/exports/exports.h +++ b/exports/exports.h @@ -11,8 +11,7 @@ typedef int (*StateCB)(int oldstate, int newstate, void* data); typedef void (*RefreshList)(); typedef void (*TokenGetter)(const char* server_id, int server_type, char* out, size_t len); typedef void (*TokenSetter)(const char* server_id, int server_type, const char* tokens); -typedef void (*ProxySetup)(int fd, const char* peer_ips); -typedef void (*ProxyReady)(); +typedef void (*ProxySetup)(int fd); static long long int get_read_rx_bytes(ReadRxBytes read) { @@ -34,13 +33,9 @@ static void call_token_setter(TokenSetter setter, const char* server_id, int ser { setter(server_id, server_type, tokens); } -static void call_proxy_setup(ProxySetup proxysetup, int fd, const char* peer_ips) +static void call_proxy_setup(ProxySetup proxysetup, int fd) { - proxysetup(fd, peer_ips); -} -static void call_proxy_ready(ProxyReady ready) -{ - ready(); + proxysetup(fd); } #endif /* EXPORTS_H */ -- cgit v1.2.3