github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/net_windows.go (about) 1 //go:build windows 2 // +build windows 3 4 /* 5 * Copyright (c) 2022, Psiphon Inc. 6 * All rights reserved. 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * 21 */ 22 23 package psiphon 24 25 import ( 26 "context" 27 "net" 28 "strconv" 29 "syscall" 30 31 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors" 32 "golang.org/x/net/bpf" 33 ) 34 35 func ClientBPFEnabled() bool { 36 return false 37 } 38 39 func setSocketBPF(_ []bpf.RawInstruction, _ int) error { 40 return errors.TraceNew("BPF not supported") 41 } 42 43 func setAdditionalSocketOptions(_ int) { 44 } 45 46 func makeLocalProxyListener(listenIP string, port int) (net.Listener, bool, error) { 47 listenConfig := net.ListenConfig{ 48 Control: func(_, _ string, c syscall.RawConn) error { 49 var controlErr error 50 err := c.Control(func(fd uintptr) { 51 52 if listenIP != "0.0.0.0" && listenIP != "::" { 53 return 54 } 55 56 // When binding to a wildcard IP address, 0.0.0.0 or ::, set 57 // SO_EXCLUSIVEADDRUSE since Windows, in this case, otherwise 58 // allows other programs to bind to a specific IP address 59 // (e.g., 127.0.0.1) with the same port number and we'll 60 // unexpectedly lose our port binding. 61 // 62 // SO_EXCLUSIVEADDRUSE is not necessary in the non-wildcard 63 // case, as Windows will cause conflicting bind calls to 64 // fail. 65 66 // SO_EXCLUSIVEADDRUSE isn't defined in syscall. This is the 67 // definition from Winsock2.h. 68 SO_EXCLUSIVEADDRUSE := ^syscall.SO_REUSEADDR 69 70 controlErr = syscall.SetsockoptInt( 71 syscall.Handle(fd), 72 syscall.SOL_SOCKET, 73 SO_EXCLUSIVEADDRUSE, 74 1) 75 }) 76 if controlErr != nil { 77 return errors.Trace(controlErr) 78 } 79 return errors.Trace(err) 80 }, 81 } 82 listener, err := listenConfig.Listen( 83 context.Background(), "tcp", net.JoinHostPort(listenIP, strconv.Itoa(port))) 84 if err != nil { 85 return nil, IsAddressInUseError(err), errors.Trace(err) 86 } 87 return listener, false, nil 88 }