/* GoVPN -- simple secure free software virtual private network daemon Copyright (C) 2014-2016 Sergey Matveev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package govpn import ( "io" ) type TAP struct { Name string Sink chan []byte dev io.ReadWriter buf0 []byte buf1 []byte bufZ bool } var ( taps = make(map[string]*TAP) ) func NewTAP(ifaceName string, mtu int) (*TAP, error) { tapRaw, err := newTAPer(ifaceName) if err != nil { return nil, err } tap := TAP{ Name: ifaceName, dev: tapRaw, buf0: make([]byte, mtu), buf1: make([]byte, mtu), Sink: make(chan []byte), } go func() { var n int var err error var buf []byte for { if tap.bufZ { buf = tap.buf0 } else { buf = tap.buf1 } tap.bufZ = !tap.bufZ n, err = tap.dev.Read(buf) if err != nil { panic("Reading TAP:" + err.Error()) } tap.Sink <- buf[:n] } }() return &tap, nil } func (t *TAP) Write(data []byte) (n int, err error) { return t.dev.Write(data) } func TAPListen(ifaceName string, mtu int) (*TAP, error) { tap, exists := taps[ifaceName] if exists { return tap, nil } tap, err := NewTAP(ifaceName, mtu) if err != nil { return nil, err } taps[ifaceName] = tap return tap, nil }