X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fgovpn%2Ftap.go;h=6485501479aaf4b4c12d8912d11ffdc86ca3ce96;hb=8f32c1c115a7f686d9cbec4f35b930cbf53e6b21;hp=f24630a1e59067acacbd305b711f77f19f677ea4;hpb=c4ce2306df402e03b7fd0f2f10e07cf21b2babc2;p=govpn.git diff --git a/src/cypherpunks.ru/govpn/tap.go b/src/cypherpunks.ru/govpn/tap.go index f24630a..6485501 100644 --- a/src/cypherpunks.ru/govpn/tap.go +++ b/src/cypherpunks.ru/govpn/tap.go @@ -1,6 +1,6 @@ /* GoVPN -- simple secure free software virtual private network daemon -Copyright (C) 2014-2017 Sergey Matveev +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 @@ -20,24 +20,34 @@ package govpn import ( "io" + + "github.com/Sirupsen/logrus" + "github.com/pkg/errors" +) + +const ( + interfaceTap = "tap" + interfaceTun = "tun" ) // TAP is a TUN or a TAP interface. +// TODO: rename to something more... generic? type TAP struct { Name string Sink chan []byte - dev io.ReadWriter + dev io.ReadWriteCloser } var ( - taps = make(map[string]*TAP) + taps = make(map[string]*TAP) + errUnsupportedInterface = errors.New("Unsupported interface") ) // NewTAP creates a new TUN/TAP virtual interface func NewTAP(ifaceName string, mtu int) (*TAP, error) { - tapRaw, err := newTAPer(ifaceName) + tapRaw, err := newTAPer(&ifaceName) if err != nil { - return nil, err + return nil, errors.Wrap(err, "newTAPer") } tap := TAP{ Name: ifaceName, @@ -60,7 +70,15 @@ func NewTAP(ifaceName string, mtu int) (*TAP, error) { bufZ = !bufZ n, err = tap.dev.Read(buf) if err != nil { - panic("Reading TUN/TAP:" + err.Error()) + logger.WithError(err).WithFields(logrus.Fields{ + "func": logFuncPrefix + "TAP read sink loop", + "name": tap.Name, + "mtu": mtu, + }).Error("Can't read interface") + return + // TODO: need a way to warn consumer that something is wrong + // TODO: to force peer to just disconnect + // TODO: use the client/server error channel? } tap.Sink <- buf[:n] } @@ -68,8 +86,15 @@ func NewTAP(ifaceName string, mtu int) (*TAP, error) { return &tap, nil } -func (t *TAP) Write(data []byte) (n int, err error) { - return t.dev.Write(data) +func (t *TAP) Write(data []byte) (int, error) { + n, err := t.dev.Write(data) + return n, errors.Wrapf(err, "t.dev.Write %d", len(data)) +} + +// Close close TAP/TUN virtual network interface +func (t *TAP) Close() error { + // TODO add chan to stop read loop + return t.dev.Close() } // TAPListen opens an existing TAP (creates if none exists) @@ -80,7 +105,7 @@ func TAPListen(ifaceName string, mtu int) (*TAP, error) { } tap, err := NewTAP(ifaceName, mtu) if err != nil { - return nil, err + return nil, errors.Wrap(err, "NewTAP") } taps[ifaceName] = tap return tap, nil