tun_windows.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //go:build windows
  2. package tun
  3. import (
  4. "golang.org/x/sys/windows"
  5. "golang.zx2c4.com/wintun"
  6. "gvisor.dev/gvisor/pkg/tcpip/stack"
  7. )
  8. // WindowsTun is an object that handles tun network interface on Windows
  9. // current version is heavily stripped to do nothing more,
  10. // then create a network interface, to be provided as endpoint to gVisor ip stack
  11. type WindowsTun struct {
  12. options TunOptions
  13. adapter *wintun.Adapter
  14. session wintun.Session
  15. MTU uint32
  16. }
  17. // WindowsTun implements Tun
  18. var _ Tun = (*WindowsTun)(nil)
  19. // WindowsTun implements GVisorTun
  20. var _ GVisorTun = (*WindowsTun)(nil)
  21. // NewTun creates a Wintun interface with the given name. Should a Wintun
  22. // interface with the same name exist, it tried to be reused.
  23. func NewTun(options TunOptions) (Tun, error) {
  24. // instantiate wintun adapter
  25. adapter, err := open(options.Name)
  26. if err != nil {
  27. return nil, err
  28. }
  29. // start the interface with ring buffer capacity of 8 MiB
  30. session, err := adapter.StartSession(0x800000)
  31. if err != nil {
  32. _ = adapter.Close()
  33. return nil, err
  34. }
  35. tun := &WindowsTun{
  36. options: options,
  37. adapter: adapter,
  38. session: session,
  39. // there is currently no iphndl.dll support, which is the netlink library for windows
  40. // so there is nowhere to change MTU for the Wintun interface, and we take its default value
  41. MTU: wintun.PacketSizeMax,
  42. }
  43. return tun, nil
  44. }
  45. func open(name string) (*wintun.Adapter, error) {
  46. var guid *windows.GUID
  47. // try to open existing adapter by name
  48. adapter, err := wintun.OpenAdapter(name)
  49. if err == nil {
  50. return adapter, nil
  51. }
  52. // try to create adapter anew
  53. adapter, err = wintun.CreateAdapter(name, "Xray", guid)
  54. if err == nil {
  55. return adapter, nil
  56. }
  57. return nil, err
  58. }
  59. func (t *WindowsTun) Start() error {
  60. return nil
  61. }
  62. func (t *WindowsTun) Close() error {
  63. t.session.End()
  64. _ = t.adapter.Close()
  65. return nil
  66. }
  67. // newEndpoint builds new gVisor stack.LinkEndpoint (WintunEndpoint) on top of WindowsTun
  68. func (t *WindowsTun) newEndpoint() (stack.LinkEndpoint, error) {
  69. return &WintunEndpoint{tun: t}, nil
  70. }