2024-05-07 12:28:30 +02:00
|
|
|
package net
|
|
|
|
|
2024-11-26 23:34:27 +01:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
"syscall"
|
|
|
|
)
|
2024-05-07 12:28:30 +02:00
|
|
|
|
|
|
|
var (
|
|
|
|
androidProtectSocketLock sync.Mutex
|
|
|
|
androidProtectSocket func(fd int32) bool
|
|
|
|
)
|
|
|
|
|
2024-11-26 23:34:27 +01:00
|
|
|
func SetAndroidProtectSocketFn(fn func(fd int32) bool) {
|
2024-05-07 12:28:30 +02:00
|
|
|
androidProtectSocketLock.Lock()
|
2024-11-26 23:34:27 +01:00
|
|
|
androidProtectSocket = fn
|
2024-05-07 12:28:30 +02:00
|
|
|
androidProtectSocketLock.Unlock()
|
|
|
|
}
|
2024-11-26 23:34:27 +01:00
|
|
|
|
|
|
|
// ControlProtectSocket is a Control function that sets the fwmark on the socket
|
|
|
|
func ControlProtectSocket(_, _ string, c syscall.RawConn) error {
|
|
|
|
var aErr error
|
|
|
|
err := c.Control(func(fd uintptr) {
|
|
|
|
androidProtectSocketLock.Lock()
|
|
|
|
defer androidProtectSocketLock.Unlock()
|
|
|
|
|
|
|
|
if androidProtectSocket == nil {
|
|
|
|
aErr = fmt.Errorf("socket protection function not set")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if !androidProtectSocket(int32(fd)) {
|
|
|
|
aErr = fmt.Errorf("failed to protect socket via Android")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return aErr
|
|
|
|
}
|