tun.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2025 The frp Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package vnet
  15. import (
  16. "context"
  17. "io"
  18. "github.com/fatedier/golib/pool"
  19. "golang.zx2c4.com/wireguard/tun"
  20. )
  21. const (
  22. offset = 16
  23. defaultPacketSize = 1420
  24. )
  25. type TunDevice interface {
  26. io.ReadWriteCloser
  27. }
  28. func OpenTun(ctx context.Context, addr string) (TunDevice, error) {
  29. td, err := openTun(ctx, addr)
  30. if err != nil {
  31. return nil, err
  32. }
  33. mtu, err := td.MTU()
  34. if err != nil {
  35. mtu = defaultPacketSize
  36. }
  37. bufferSize := max(mtu, defaultPacketSize)
  38. batchSize := td.BatchSize()
  39. device := &tunDeviceWrapper{
  40. dev: td,
  41. bufferSize: bufferSize,
  42. readBuffers: make([][]byte, batchSize),
  43. sizeBuffer: make([]int, batchSize),
  44. }
  45. for i := range device.readBuffers {
  46. device.readBuffers[i] = make([]byte, offset+bufferSize)
  47. }
  48. return device, nil
  49. }
  50. type tunDeviceWrapper struct {
  51. dev tun.Device
  52. bufferSize int
  53. readBuffers [][]byte
  54. packetBuffers [][]byte
  55. sizeBuffer []int
  56. }
  57. func (d *tunDeviceWrapper) Read(p []byte) (int, error) {
  58. if len(d.packetBuffers) > 0 {
  59. n := copy(p, d.packetBuffers[0])
  60. d.packetBuffers = d.packetBuffers[1:]
  61. return n, nil
  62. }
  63. n, err := d.dev.Read(d.readBuffers, d.sizeBuffer, offset)
  64. if err != nil {
  65. return 0, err
  66. }
  67. if n == 0 {
  68. return 0, io.EOF
  69. }
  70. for i := range n {
  71. if d.sizeBuffer[i] <= 0 {
  72. continue
  73. }
  74. d.packetBuffers = append(d.packetBuffers, d.readBuffers[i][offset:offset+d.sizeBuffer[i]])
  75. }
  76. dataSize := copy(p, d.packetBuffers[0])
  77. d.packetBuffers = d.packetBuffers[1:]
  78. return dataSize, nil
  79. }
  80. func (d *tunDeviceWrapper) Write(p []byte) (int, error) {
  81. buf := pool.GetBuf(offset + d.bufferSize)
  82. defer pool.PutBuf(buf)
  83. n := copy(buf[offset:], p)
  84. _, err := d.dev.Write([][]byte{buf[:offset+n]}, offset)
  85. return n, err
  86. }
  87. func (d *tunDeviceWrapper) Close() error {
  88. return d.dev.Close()
  89. }