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 New Issue
	
	Block a user