net_windows.go 2.4 KB

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