veyron/profiles/net: initial pass at dhcp support.
Change-Id: I1ab0b9bcc7e1cb239d608995ca687e1e19c2375a
diff --git a/profiles/net/gce_linux.go b/profiles/net/gce_linux.go
index fa09109..d350880 100644
--- a/profiles/net/gce_linux.go
+++ b/profiles/net/gce_linux.go
@@ -31,7 +31,7 @@
if _, err := publisher.CreateStream(StreamName, "network configuration", ch); err != nil {
return false
}
- publishInitialSettings(ch, listen_protocol, listen_addr.IP.String(), pub)
+ publishInitialSettings(ch, listenProtocolFlag.Protocol, listenSpecFlag.String(), pub)
return true
}
return false
diff --git a/profiles/net/init.go b/profiles/net/init.go
index 34f577d..e38a6f5 100644
--- a/profiles/net/init.go
+++ b/profiles/net/init.go
@@ -38,13 +38,13 @@
)
var (
- listen_protocol string
- listen_addr config.IPFlag
+ listenProtocolFlag = config.TCPProtocolFlag{"tcp4"}
+ listenSpecFlag = config.IPHostPortFlag{Port: ":0"}
)
func init() {
- flag.StringVar(&listen_protocol, "veyron.protocol", "tcp4", "protocol to listen with")
- flag.Var(&listen_addr, "veyron.address", "address to listen on")
+ flag.Var(&listenProtocolFlag, "veyron.tcpprotocol", "protocol to listen with")
+ flag.Var(&listenSpecFlag, "veyron.tcpaddress", "address to listen on")
rt.RegisterProfile(New())
}
@@ -99,7 +99,7 @@
log.Errorf("failed to create publisher: %s", err)
return
}
- go monitorAndPublishNetworkSettings(rt, stop, ch, listen_protocol, listen_addr.IP.String())
+ go monitorAndPublishNetworkSettings(rt, stop, ch, listenProtocolFlag.Protocol, listenSpecFlag)
}
func publishInitialSettings(ch chan<- config.Setting, protocol, listenSpec string, addr net.IP) {
@@ -118,19 +118,24 @@
// RmPublishAddressSetting without first sending an AddPublishAddressSetting.
func monitorAndPublishNetworkSettings(rt veyron2.Runtime, stop <-chan struct{},
ch chan<- config.Setting,
- listenProtocol string, listenSpec string) {
+ listenProtocol string, listenSpec config.IPHostPortFlag) {
defer close(ch)
log := rt.Logger()
+
prev4, _, prevAddr := firstUsableIPv4()
+ // TODO(cnicolaou): check that prev4 is one of the IPs that a hostname
+ // resolved to, if we used a hostname in the listenspec.
+
// prevAddr may be nil if we are currently offline.
- publishInitialSettings(ch, listenProtocol, listenSpec, prevAddr)
+ log.Infof("Initial Settings: %s %s publish %s", listenProtocol, listenSpec, prevAddr)
+ publishInitialSettings(ch, listenProtocol, listenSpec.String(), prevAddr)
// Start the dhcp watcher.
watcher, err := netconfig.NewNetConfigWatcher()
if err != nil {
- log.VI(1).Infof("Failed to get new config watcher: %s", err)
+ log.VI(2).Infof("Failed to get new config watcher: %s", err)
<-stop
return
}
@@ -139,16 +144,40 @@
select {
case <-watcher.Channel():
cur4, _, _ := ipState()
- added := findAdded(prev4, cur4)
- ifc, newAddr := added.first()
- log.VI(1).Infof("new address found: %s:%s", ifc, newAddr)
removed := findRemoved(prev4, cur4)
- if prevAddr == nil || (removed.has(prevAddr) && newAddr != nil) {
- log.VI(1).Infof("address change from %s to %s:%s",
+ added := findAdded(prev4, cur4)
+ log.VI(2).Infof("Previous: %d: %s", len(prev4), prev4)
+ log.VI(2).Infof("Current : %d: %s", len(cur4), cur4)
+ log.VI(2).Infof("Added : %d: %s", len(added), added)
+ log.VI(2).Infof("Removed : %d: %s", len(removed), removed)
+ if len(removed) == 0 && len(added) == 0 {
+ log.VI(2).Infof("Network event that lead to no address changes since our last 'baseline'")
+ continue
+ }
+ if len(added) == 0 {
+ // Nothing has been added, but something has been removed.
+ if !removed.has(prevAddr) {
+ log.VI(1).Infof("An address we were not using was removed")
+ continue
+ }
+ log.Infof("Publish address is no longer available: %s", prevAddr)
+ // Our currently published address has been removed and
+ // a new one has not been added.
+ // TODO(cnicolaou): look for a new address to use right now.
+ prevAddr = nil
+ continue
+ }
+ log.Infof("At least one address has been added and zero or more removed")
+ // something has been added, and maybe something has been removed
+ ifc, newAddr := added.first()
+ if newAddr != nil && (prevAddr == nil || removed.has(prevAddr)) {
+ log.Infof("Address being changed from %s to %s:%s",
prevAddr, ifc, newAddr)
ch <- config.NewIP(AddPublishAddressSetting, "new dhcp address to publish", newAddr)
ch <- config.NewIP(RmPublishAddressSetting, "remove address", prevAddr)
prevAddr = newAddr
+ prev4 = cur4
+ log.VI(2).Infof("Network baseline set to %s", cur4)
}
case <-stop:
return
diff --git a/profiles/net/net_test.go b/profiles/net/net_test.go
index ef862dc..31b88a8 100644
--- a/profiles/net/net_test.go
+++ b/profiles/net/net_test.go
@@ -56,7 +56,7 @@
}
// missing interfaces
- got, want = findRemoved(aif, bif), ipAndIf{"eth0": nil, "eth1": nil}
+ got, want = findRemoved(aif, bif), aif
if !reflect.DeepEqual(got, want) {
t.Errorf("got %s, want %s", got, want)
}
@@ -65,7 +65,7 @@
bif["eth0"] = []net.IP{a, b, a6, b6}
got, want = findRemoved(aif, bif), ipAndIf{
"eth0": []net.IP{c, c6},
- "eth1": nil,
+ "eth1": aif["eth1"],
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %s, want %s", got, want)
diff --git a/profiles/net/main.go b/profiles/net/net_watcher.go
similarity index 100%
rename from profiles/net/main.go
rename to profiles/net/net_watcher.go
diff --git a/profiles/net/util.go b/profiles/net/util.go
index cee7e63..721ed29 100644
--- a/profiles/net/util.go
+++ b/profiles/net/util.go
@@ -65,10 +65,11 @@
continue
}
for _, addr := range addrs {
- if _, ok := addr.(*net.IPAddr); ok {
+ ipn, ok := addr.(*net.IPNet)
+ if !ok {
continue
}
- ip := net.ParseIP(addr.String())
+ ip := ipn.IP
if ip == nil || ip.IsLoopback() {
continue
}
@@ -114,15 +115,11 @@
return netconfig.IsGloballyRoutable(ip)
}
-func diffAB(a, b ipAndIf, added bool) ipAndIf {
+func diffAB(a, b ipAndIf) ipAndIf {
diff := make(ipAndIf)
for ak, av := range a {
if b[ak] == nil {
- if added {
- diff[ak] = av
- } else {
- diff[ak] = nil
- }
+ diff[ak] = av
continue
}
for _, v := range av {
@@ -144,11 +141,11 @@
// findAdded returns the set of interfaces and/or addresses that are
// present in b, but not in a - i.e. have been added.
func findAdded(a, b ipAndIf) ipAndIf {
- return diffAB(b, a, true)
+ return diffAB(b, a)
}
// findRemoved returns the set of interfaces and/or addresses that
// are present in a, but not in b - i.e. have been removed.
func findRemoved(a, b ipAndIf) ipAndIf {
- return diffAB(a, b, false)
+ return diffAB(a, b)
}