]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
tun: windows: delay initial write
authorJason A. Donenfeld <Jason@zx2c4.com>
Thu, 4 Jul 2019 20:41:42 +0000 (22:41 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Thu, 4 Jul 2019 20:41:42 +0000 (22:41 +0200)
Otherwise we provoke Wintun 0.3.

tun/tun_windows.go

index 543482eb2bfa656432b94f18ec5c90702f23cb5e..613bc9f40bc1f51dc74fcdde897d992fcd474dae 100644 (file)
@@ -11,6 +11,7 @@ import (
        "io"
        "os"
        "sync"
+       "sync/atomic"
        "time"
        "unsafe"
 
@@ -38,16 +39,17 @@ type exchgBufWrite struct {
 }
 
 type NativeTun struct {
-       wt           *wintun.Wintun
-       tunFileRead  *os.File
-       tunFileWrite *os.File
-       tunLock      sync.Mutex
-       close        bool
-       rdBuff       *exchgBufRead
-       wrBuff       *exchgBufWrite
-       events       chan Event
-       errors       chan error
-       forcedMTU    int
+       wt                        *wintun.Wintun
+       tunFileRead               *os.File
+       tunFileWrite              *os.File
+       haveRegisteredWriteBuffer int32
+       tunLock                   sync.Mutex
+       close                     bool
+       rdBuff                    *exchgBufRead
+       wrBuff                    *exchgBufWrite
+       events                    chan Event
+       errors                    chan error
+       forcedMTU                 int
 }
 
 func packetAlign(size uint32) uint32 {
@@ -140,12 +142,7 @@ func (tun *NativeTun) openTUN() error {
                        }
                        return err
                }
-               firstSize := (*uint32)(unsafe.Pointer(&tun.wrBuff.data[0]))
-               saved := *firstSize
-               *firstSize = 0
-               // Set the maximum buffer length with an invalid write.
-               tun.tunFileWrite.Write(tun.wrBuff.data[:])
-               *firstSize = saved
+               atomic.StoreInt32(&tun.haveRegisteredWriteBuffer, 0)
        }
        return nil
 }
@@ -324,6 +321,15 @@ func (tun *NativeTun) Flush() error {
                        return err
                }
 
+               if atomic.CompareAndSwapInt32(&tun.haveRegisteredWriteBuffer, 0, 1) {
+                       firstSize := (*uint32)(unsafe.Pointer(&tun.wrBuff.data[0]))
+                       saved := *firstSize
+                       *firstSize = 0
+                       // Set the maximum buffer length with an invalid write.
+                       tun.tunFileWrite.Write(tun.wrBuff.data[:])
+                       *firstSize = saved
+               }
+
                for {
                        _, err = file.Write(tun.wrBuff.data[:tun.wrBuff.offset])
                        if err != nil {