diff options
| author | Jeroen Wijenbergh <jeroen.wijenbergh@geant.org> | 2025-09-03 10:13:46 +0200 |
|---|---|---|
| committer | Jeroen Wijenbergh <jeroen.wijenbergh@geant.org> | 2025-09-03 10:53:42 +0200 |
| commit | c3318fb386096170282e831eb3b616a5a7e9dda8 (patch) | |
| tree | 0367fdad43a02da49b278f38db9b8e15d3de908a /exports | |
| parent | 5e05784cab953b0e24609398106dd33da7738d21 (diff) | |
Revert "All: Remove ProxyGuard integration"
This partially reverts commit 6b939462fb1064abd42e8cb8316700ec844172ea.
It keeps the proxyguard functions but leaves GetConfig alone. E.g. no WireGuard config replacing and querying is happening for ProxyGuard.
Needed for the Linux client as I have not found a good way to have a daemon with NetworkManager integration
Diffstat (limited to 'exports')
| -rw-r--r-- | exports/exports.go | 107 | ||||
| -rw-r--r-- | exports/exports.h | 5 |
2 files changed, 112 insertions, 0 deletions
diff --git a/exports/exports.go b/exports/exports.go index a20ffb8..3ef6781 100644 --- a/exports/exports.go +++ b/exports/exports.go @@ -27,6 +27,7 @@ import ( "codeberg.org/eduVPN/eduvpn-common/client" "codeberg.org/eduVPN/eduvpn-common/i18n/err" + "codeberg.org/eduVPN/eduvpn-common/proxy" "codeberg.org/eduVPN/eduvpn-common/types/cookie" errtypes "codeberg.org/eduVPN/eduvpn-common/types/error" srvtypes "codeberg.org/eduVPN/eduvpn-common/types/server" @@ -876,6 +877,112 @@ func StartFailover(c C.uintptr_t, gateway *C.char, mtu C.int, readRxBytes C.Read return droppedC, nil } +// NewProxyguard creates the 'proxyguard' procedure in eduvpn-common. +// 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. +// - `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 +// +// Example Input: ```NewProxyguard(myCookie, 1337, 0, "5.5.5.5:51820", proxySetupCB)``` +// +// Example Output: ```null``` +// +//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 0, getCError(err) + } + proxy, proxyErr := proxy.NewProxyguard(ck.Context(), int(lp), int(tcpsp), C.GoString(peer), func(fd int) { + if proxySetup == nil { + return + } + C.call_proxy_setup(proxySetup, C.int(fd)) + }) + if proxyErr != nil { + return 0, getCError(proxyErr) + } + return C.uintptr_t(cgo.NewHandle(proxy)), nil +} + +// ProxyguardRestart restarts ProxyGuard, call this when a network change happens +// +// Example Input: ```ProxyguardRestart(proxyHandle)``` +// +// Example Output: ```"failed restarting ProxyGuard"``` +// +//export ProxyguardRestart +func ProxyguardRestart(proxyH C.uintptr_t) *C.char { + pr, err := getProxy(proxyH) + if err != nil { + return getCError(err) + } + pr.Restart() + return 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 +} + +// ProxyguardTunnel starts the tunneling for ProxyGuard +// `c` is the cookie +// `proxyH` is the proxy handle +// `wglisten` is the port WireGuard is listening on +// +//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) +} + +// ProxyguardPeerIPs gets the Peer IPs configured by ProxyGuard +// Example Input: ```ProxyguardPeerIPs(handle)``` +// +// Example Output: ```["1.1.1.1"], null``` +// +//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. // // Note: this transitions the FSM into the new state without passing any data to it. diff --git a/exports/exports.h b/exports/exports.h index 13630a6..9ec39e4 100644 --- a/exports/exports.h +++ b/exports/exports.h @@ -11,6 +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); static long long int get_read_rx_bytes(ReadRxBytes read) { @@ -32,5 +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) +{ + proxysetup(fd); +} #endif /* EXPORTS_H */ |
