device: return error from Up() and Down()
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
6f08a10041
commit
587a2b2a20
|
@ -139,37 +139,42 @@ func removePeerLocked(device *Device, peer *Peer, key NoisePublicKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// changeState attempts to change the device state to match want.
|
// changeState attempts to change the device state to match want.
|
||||||
func (device *Device) changeState(want deviceState) {
|
func (device *Device) changeState(want deviceState) (err error) {
|
||||||
device.state.Lock()
|
device.state.Lock()
|
||||||
defer device.state.Unlock()
|
defer device.state.Unlock()
|
||||||
old := device.deviceState()
|
old := device.deviceState()
|
||||||
if old == deviceStateClosed {
|
if old == deviceStateClosed {
|
||||||
// once closed, always closed
|
// once closed, always closed
|
||||||
device.log.Verbosef("Interface closed, ignored requested state %s", want)
|
device.log.Verbosef("Interface closed, ignored requested state %s", want)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
switch want {
|
switch want {
|
||||||
case old:
|
case old:
|
||||||
return
|
return nil
|
||||||
case deviceStateUp:
|
case deviceStateUp:
|
||||||
atomic.StoreUint32(&device.state.state, uint32(deviceStateUp))
|
atomic.StoreUint32(&device.state.state, uint32(deviceStateUp))
|
||||||
if ok := device.upLocked(); ok {
|
err = device.upLocked()
|
||||||
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
fallthrough // up failed; bring the device all the way back down
|
fallthrough // up failed; bring the device all the way back down
|
||||||
case deviceStateDown:
|
case deviceStateDown:
|
||||||
atomic.StoreUint32(&device.state.state, uint32(deviceStateDown))
|
atomic.StoreUint32(&device.state.state, uint32(deviceStateDown))
|
||||||
device.downLocked()
|
errDown := device.downLocked()
|
||||||
|
if err == nil {
|
||||||
|
err = errDown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
device.log.Verbosef("Interface state was %s, requested %s, now %s", old, want, device.deviceState())
|
device.log.Verbosef("Interface state was %s, requested %s, now %s", old, want, device.deviceState())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// upLocked attempts to bring the device up and reports whether it succeeded.
|
// upLocked attempts to bring the device up and reports whether it succeeded.
|
||||||
// The caller must hold device.state.mu and is responsible for updating device.state.state.
|
// The caller must hold device.state.mu and is responsible for updating device.state.state.
|
||||||
func (device *Device) upLocked() bool {
|
func (device *Device) upLocked() error {
|
||||||
if err := device.BindUpdate(); err != nil {
|
if err := device.BindUpdate(); err != nil {
|
||||||
device.log.Errorf("Unable to update bind: %v", err)
|
device.log.Errorf("Unable to update bind: %v", err)
|
||||||
return false
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
device.peers.RLock()
|
device.peers.RLock()
|
||||||
|
@ -180,12 +185,12 @@ func (device *Device) upLocked() bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
device.peers.RUnlock()
|
device.peers.RUnlock()
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// downLocked attempts to bring the device down.
|
// downLocked attempts to bring the device down.
|
||||||
// The caller must hold device.state.mu and is responsible for updating device.state.state.
|
// The caller must hold device.state.mu and is responsible for updating device.state.state.
|
||||||
func (device *Device) downLocked() {
|
func (device *Device) downLocked() error {
|
||||||
err := device.BindClose()
|
err := device.BindClose()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
device.log.Errorf("Bind close failed: %v", err)
|
device.log.Errorf("Bind close failed: %v", err)
|
||||||
|
@ -196,14 +201,15 @@ func (device *Device) downLocked() {
|
||||||
peer.Stop()
|
peer.Stop()
|
||||||
}
|
}
|
||||||
device.peers.RUnlock()
|
device.peers.RUnlock()
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) Up() {
|
func (device *Device) Up() error {
|
||||||
device.changeState(deviceStateUp)
|
return device.changeState(deviceStateUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) Down() {
|
func (device *Device) Down() error {
|
||||||
device.changeState(deviceStateDown)
|
return device.changeState(deviceStateDown)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) IsUnderLoad() bool {
|
func (device *Device) IsUnderLoad() bool {
|
||||||
|
|
|
@ -157,14 +157,13 @@ func genTestPair(tb testing.TB) (pair testPair) {
|
||||||
level = LogLevelError
|
level = LogLevelError
|
||||||
}
|
}
|
||||||
p.dev = NewDevice(p.tun.TUN(), NewLogger(level, fmt.Sprintf("dev%d: ", i)))
|
p.dev = NewDevice(p.tun.TUN(), NewLogger(level, fmt.Sprintf("dev%d: ", i)))
|
||||||
p.dev.Up()
|
|
||||||
if err := p.dev.IpcSet(cfg[i]); err != nil {
|
if err := p.dev.IpcSet(cfg[i]); err != nil {
|
||||||
tb.Errorf("failed to configure device %d: %v", i, err)
|
tb.Errorf("failed to configure device %d: %v", i, err)
|
||||||
p.dev.Close()
|
p.dev.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !p.dev.isUp() {
|
if err := p.dev.Up(); err != nil {
|
||||||
tb.Errorf("device %d did not come up", i)
|
tb.Errorf("failed to bring up device %d: %v", i, err)
|
||||||
p.dev.Close()
|
p.dev.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -212,9 +211,13 @@ func TestUpDown(t *testing.T) {
|
||||||
go func(d *Device) {
|
go func(d *Device) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for i := 0; i < itrials; i++ {
|
for i := 0; i < itrials; i++ {
|
||||||
d.Up()
|
if err := d.Up(); err != nil {
|
||||||
|
t.Errorf("failed up bring up device: %v", err)
|
||||||
|
}
|
||||||
time.Sleep(time.Duration(rand.Intn(int(time.Nanosecond * (0x10000 - 1)))))
|
time.Sleep(time.Duration(rand.Intn(int(time.Nanosecond * (0x10000 - 1)))))
|
||||||
d.Down()
|
if err := d.Down(); err != nil {
|
||||||
|
t.Errorf("failed to bring down device: %v", err)
|
||||||
|
}
|
||||||
time.Sleep(time.Duration(rand.Intn(int(time.Nanosecond * (0x10000 - 1)))))
|
time.Sleep(time.Duration(rand.Intn(int(time.Nanosecond * (0x10000 - 1)))))
|
||||||
}
|
}
|
||||||
}(pair[i].dev)
|
}(pair[i].dev)
|
||||||
|
|
|
@ -48,7 +48,11 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
device := device.NewDevice(tun, logger)
|
device := device.NewDevice(tun, logger)
|
||||||
device.Up()
|
err = device.Up()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to bring up device: %v", err)
|
||||||
|
os.Exit(ExitSetupFailed)
|
||||||
|
}
|
||||||
logger.Verbosef("Device started")
|
logger.Verbosef("Device started")
|
||||||
|
|
||||||
uapi, err := ipc.UAPIListen(interfaceName)
|
uapi, err := ipc.UAPIListen(interfaceName)
|
||||||
|
|
|
@ -31,7 +31,10 @@ public_key=25123c5dcd3328ff645e4f2a3fce0d754400d3887a0cb7c56f0267e20fbf3c5b
|
||||||
endpoint=163.172.161.0:12912
|
endpoint=163.172.161.0:12912
|
||||||
allowed_ip=0.0.0.0/0
|
allowed_ip=0.0.0.0/0
|
||||||
`)
|
`)
|
||||||
dev.Up()
|
err = dev.Up()
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
client := http.Client{
|
client := http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
|
|
Loading…
Reference in a new issue