diff --git a/router/gossip_test.go b/router/gossip_test.go index 050d48e7..cc8c6a9d 100644 --- a/router/gossip_test.go +++ b/router/gossip_test.go @@ -19,7 +19,7 @@ type mockChannelConnection struct { // We need to create some dummy channels otherwise tests hang on nil // channels when Router.OnGossip() calls async methods. func NewTestRouter(name PeerName) *Router { - router := NewRouter(nil, name, nil, 10, 1024, nil) + router := NewRouter(nil, name, "", nil, 10, 1024, nil) router.ConnectionMaker.queryChan = make(chan *ConnectionMakerInteraction, ChannelSize) router.Routes.queryChan = make(chan *Interaction, ChannelSize) return router @@ -35,8 +35,8 @@ func (router *Router) AddTestChannelConnection(r *Router) { fromName := router.Ourself.Peer.Name toName := r.Ourself.Peer.Name - fromPeer := NewPeer(fromName, router.Ourself.Peer.UID, 0) - toPeer := NewPeer(toName, r.Ourself.Peer.UID, 0) + fromPeer := NewPeer(fromName, "", router.Ourself.Peer.UID, 0) + toPeer := NewPeer(toName, "", r.Ourself.Peer.UID, 0) r.Peers.FetchWithDefault(fromPeer) // Has side-effect of incrementing refcount router.Peers.FetchWithDefault(toPeer) // @@ -70,10 +70,10 @@ func TestGossipTopology(t *testing.T) { // the routers supplied as arguments, carrying across all UID and // version information. func (router *Router) tp(routers ...*Router) *Peer { - peer := NewPeer(router.Ourself.Peer.Name, router.Ourself.Peer.UID, 0) + peer := NewPeer(router.Ourself.Peer.Name, "", router.Ourself.Peer.UID, 0) connections := make(map[PeerName]Connection) for _, r := range routers { - p := NewPeer(r.Ourself.Peer.Name, r.Ourself.Peer.UID, r.Ourself.Peer.version) + p := NewPeer(r.Ourself.Peer.Name, "", r.Ourself.Peer.UID, r.Ourself.Peer.version) connections[r.Ourself.Peer.Name] = newMockConnection(peer, p) } peer.SetVersionAndConnections(router.Ourself.Peer.version, connections) diff --git a/router/handshake.go b/router/handshake.go index b0798768..d9d0ecda 100644 --- a/router/handshake.go +++ b/router/handshake.go @@ -59,6 +59,7 @@ func (conn *LocalConnection) handshake(enc *gob.Encoder, dec *gob.Decoder, accep "ProtocolVersion": versionStr, "PeerNameFlavour": PeerNameFlavour, "Name": conn.local.Name.String(), + "NickName": conn.local.NickName, "UID": fmt.Sprint(conn.local.UID), "ConnID": fmt.Sprint(localConnID)} handshakeRecv := map[string]string{} @@ -84,6 +85,7 @@ func (conn *LocalConnection) handshake(enc *gob.Encoder, dec *gob.Decoder, accep fv.CheckEqual("ProtocolVersion", versionStr) fv.CheckEqual("PeerNameFlavour", PeerNameFlavour) nameStr, _ := fv.Value("Name") + nickNameStr, _ := fv.Value("NickName") uidStr, _ := fv.Value("UID") remoteConnIdStr, _ := fv.Value("ConnID") if err := fv.Err(); err != nil { @@ -136,7 +138,7 @@ func (conn *LocalConnection) handshake(enc *gob.Encoder, dec *gob.Decoder, accep conn.Decryptor = NewNonDecryptor(conn) } - toPeer := NewPeer(name, uid, 0) + toPeer := NewPeer(name, nickNameStr, uid, 0) toPeer = conn.Router.Peers.FetchWithDefault(toPeer) switch toPeer { case nil: diff --git a/router/local_peer.go b/router/local_peer.go index 10fe70ed..1f2cf810 100644 --- a/router/local_peer.go +++ b/router/local_peer.go @@ -18,8 +18,8 @@ type PeerInteraction struct { payload interface{} } -func NewLocalPeer(name PeerName, router *Router) *LocalPeer { - return &LocalPeer{Peer: NewPeer(name, 0, 0), Router: router} +func NewLocalPeer(name PeerName, nickName string, router *Router) *LocalPeer { + return &LocalPeer{Peer: NewPeer(name, nickName, 0, 0), Router: router} } func (peer *LocalPeer) Start() { diff --git a/router/mocks_test.go b/router/mocks_test.go index 50e75d7e..2380a0fe 100644 --- a/router/mocks_test.go +++ b/router/mocks_test.go @@ -12,7 +12,7 @@ import ( // Add to peers a connection from peers.ourself to p func (peers *Peers) AddTestConnection(p *Peer) { - toPeer := NewPeer(p.Name, p.UID, 0) + toPeer := NewPeer(p.Name, "", p.UID, 0) peers.FetchWithDefault(toPeer) // Has side-effect of incrementing refcount conn := newMockConnection(peers.ourself, toPeer) peers.ourself.addConnection(conn) @@ -22,10 +22,10 @@ func (peers *Peers) AddTestConnection(p *Peer) { // Add to peers a connection from p1 to p2 func (peers *Peers) AddTestRemoteConnection(p1, p2 *Peer) { fromName := p1.Name - fromPeer := NewPeer(fromName, p1.UID, 0) + fromPeer := NewPeer(fromName, "", p1.UID, 0) fromPeer = peers.FetchWithDefault(fromPeer) toName := p2.Name - toPeer := NewPeer(toName, p2.UID, 0) + toPeer := NewPeer(toName, "", p2.UID, 0) toPeer = peers.FetchWithDefault(toPeer) peers.ourself.addConnection(&RemoteConnection{fromPeer, toPeer, "", false}) } diff --git a/router/peer.go b/router/peer.go index 09ac2d9e..86047e3a 100644 --- a/router/peer.go +++ b/router/peer.go @@ -10,19 +10,21 @@ type Peer struct { sync.RWMutex Name PeerName NameByte []byte + NickName string UID uint64 version uint64 localRefCount uint64 connections map[PeerName]Connection } -func NewPeer(name PeerName, uid uint64, version uint64) *Peer { +func NewPeer(name PeerName, nickName string, uid uint64, version uint64) *Peer { if uid == 0 { uid = randUint64() } return &Peer{ Name: name, NameByte: name.Bin(), + NickName: nickName, UID: uid, version: version, connections: make(map[PeerName]Connection)} @@ -31,7 +33,7 @@ func NewPeer(name PeerName, uid uint64, version uint64) *Peer { func (peer *Peer) String() string { peer.RLock() defer peer.RUnlock() - return fmt.Sprint("Peer ", peer.Name, " (v", peer.version, ") (UID ", peer.UID, ")") + return fmt.Sprint("Peer ", peer.Name, " (", peer.NickName, ") (v", peer.version, ") (UID ", peer.UID, ")") } func (peer *Peer) Version() uint64 { diff --git a/router/peers.go b/router/peers.go index 0217d8b0..e8540a8a 100644 --- a/router/peers.go +++ b/router/peers.go @@ -128,7 +128,7 @@ func (peers *Peers) String() string { if !conn.Established() { established = " (unestablished)" } - buf.WriteString(fmt.Sprintf(" -> %v [%v%s]\n", remoteName, conn.RemoteTCPAddr(), established)) + buf.WriteString(fmt.Sprintf(" -> %v (%v) [%v%s]\n", remoteName, conn.Remote().NickName, conn.RemoteTCPAddr(), established)) }) }) return buf.String() @@ -178,7 +178,7 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de decoder := gob.NewDecoder(updateBuf) for { - nameByte, uid, version, connsBuf, decErr := decodePeerNoConns(decoder) + nameByte, nickName, uid, version, connsBuf, decErr := decodePeerNoConns(decoder) if decErr == io.EOF { break } else if decErr != nil { @@ -186,7 +186,7 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de return } name := PeerNameFromBin(nameByte) - newPeer := NewPeer(name, uid, version) + newPeer := NewPeer(name, nickName, uid, version) decodedUpdate = append(decodedUpdate, newPeer) decodedConns = append(decodedConns, connsBuf) existingPeer, found := peers.table[name] @@ -257,6 +257,7 @@ func (peer *Peer) encode(enc *gob.Encoder) { defer peer.RUnlock() checkFatal(enc.Encode(peer.NameByte)) + checkFatal(enc.Encode(peer.NickName)) checkFatal(enc.Encode(peer.UID)) checkFatal(enc.Encode(peer.version)) @@ -271,10 +272,13 @@ func (peer *Peer) encode(enc *gob.Encoder) { checkFatal(enc.Encode(connsBuf.Bytes())) } -func decodePeerNoConns(dec *gob.Decoder) (nameByte []byte, uid uint64, version uint64, conns []byte, err error) { +func decodePeerNoConns(dec *gob.Decoder) (nameByte []byte, nickName string, uid uint64, version uint64, conns []byte, err error) { if err = dec.Decode(&nameByte); err != nil { return } + if err = dec.Decode(&nickName); err != nil { + return + } if err = dec.Decode(&uid); err != nil { return } diff --git a/router/peers_test.go b/router/peers_test.go index ecaa07b2..b3257789 100644 --- a/router/peers_test.go +++ b/router/peers_test.go @@ -17,7 +17,7 @@ import ( // - non-gc of peers that are only referenced locally func newNode(name PeerName) (*Peer, *Peers) { - peer := NewPeer(name, 0, 0) + peer := NewPeer(name, "", 0, 0) peers := NewPeers(peer, func(*Peer) {}) peers.FetchWithDefault(peer) return peer, peers diff --git a/router/protocol.go b/router/protocol.go index 7a6fff36..9db4160f 100644 --- a/router/protocol.go +++ b/router/protocol.go @@ -2,7 +2,7 @@ package router const ( Protocol = "weave" - ProtocolVersion = 12 + ProtocolVersion = 13 ) type ProtocolTag byte diff --git a/router/router.go b/router/router.go index 180a2aea..fd867ee2 100644 --- a/router/router.go +++ b/router/router.go @@ -46,7 +46,7 @@ type PacketSourceSink interface { PacketSink } -func NewRouter(iface *net.Interface, name PeerName, password []byte, connLimit int, bufSz int, logFrame func(string, []byte, *layers.Ethernet)) *Router { +func NewRouter(iface *net.Interface, name PeerName, nickName string, password []byte, connLimit int, bufSz int, logFrame func(string, []byte, *layers.Ethernet)) *Router { router := &Router{ Iface: iface, GossipChannels: make(map[uint32]*GossipChannel), @@ -63,7 +63,7 @@ func NewRouter(iface *net.Interface, name PeerName, password []byte, connLimit i router.Macs.Delete(peer) log.Println("Removed unreachable", peer) } - router.Ourself = NewLocalPeer(name, router) + router.Ourself = NewLocalPeer(name, nickName, router) router.Macs = NewMacCache(macMaxAge, onMacExpiry) router.Peers = NewPeers(router.Ourself.Peer, onPeerGC) router.Peers.FetchWithDefault(router.Ourself.Peer) @@ -94,7 +94,7 @@ func (router *Router) UsingPassword() bool { func (router *Router) Status() string { var buf bytes.Buffer - buf.WriteString(fmt.Sprintln("Our name is", router.Ourself.Name)) + buf.WriteString(fmt.Sprintln("Our name is", router.Ourself.Name, "(" + router.Ourself.NickName + ")")) buf.WriteString(fmt.Sprintln("Sniffing traffic on", router.Iface)) buf.WriteString(fmt.Sprintf("MACs:\n%s", router.Macs)) buf.WriteString(fmt.Sprintf("Peers:\n%s", router.Peers)) diff --git a/site/how-it-works.md b/site/how-it-works.md index d5d7c57b..cc52ca57 100644 --- a/site/how-it-works.md +++ b/site/how-it-works.md @@ -7,7 +7,8 @@ layout: default A weave network consists of a number of 'peers' - weave routers residing on different hosts. Each peer has a name, which tends to -remain the same over restarts, and a unique identifier (UID) which is +remain the same over restarts, a human friendly nickname for use in +status and logging output and a unique identifier (UID) which is different each time it is run. These are opaque identifiers as far as the router is concerned, although the name defaults to a MAC address. @@ -147,6 +148,8 @@ The topology update payload is laid out like this: +-----------------------------------+ | Peer 1: Name | +-----------------------------------+ + | Peer 1: NickName | + +-----------------------------------+ | Peer 1: UID | +-----------------------------------+ | Peer 1: Version number | @@ -157,6 +160,8 @@ The topology update payload is laid out like this: +-----------------------------------+ | Peer N: Name | +-----------------------------------+ + | Peer N: NickName | + +-----------------------------------+ | Peer N: UID | +-----------------------------------+ | Peer N: Version number | diff --git a/site/troubleshooting.md b/site/troubleshooting.md index 6289a67a..616bd197 100644 --- a/site/troubleshooting.md +++ b/site/troubleshooting.md @@ -58,7 +58,7 @@ This produces output like: ```` weave router 0.7.0 Encryption off -Our name is 7a:f4:56:87:76:3b +Our name is 7a:f4:56:87:76:3b (weave01) Sniffing traffic on &{39 65535 ethwe ae:e3:07:9c:8c:d4 up|broadcast|multicast} MACs: ba:8c:b9:dc:e1:c9 -> 7a:f4:56:87:76:3b (2014-10-23 16:39:19.482338935 +0000 UTC) @@ -67,10 +67,10 @@ ce:15:34:a9:b5:6d -> 7a:f4:56:87:76:3b (2014-10-23 16:39:28.257103595 +0000 UTC) 9e:95:0c:54:8e:39 -> 7a:16:dd:5b:83:de (2014-10-23 16:39:28.795601325 +0000 UTC) 72:5f:a4:60:e5:ce -> 7a:16:dd:5b:83:de (2014-10-23 16:39:29.575995255 +0000 UTC) Peers: -Peer 7a:16:dd:5b:83:de (v31) (UID 13151318985609435078) - -> 7a:f4:56:87:76:3b [37.157.33.76:7195] -Peer 7a:f4:56:87:76:3b (v1) (UID 6913268221365110570) - -> 7a:16:dd:5b:83:de [191.235.147.190:6783] +Peer 7a:16:dd:5b:83:de (weave02) (v31) (UID 13151318985609435078) + -> 7a:f4:56:87:76:3b (weave01) [37.157.33.76:7195] +Peer 7a:f4:56:87:76:3b (weave01) (v1) (UID 6913268221365110570) + -> 7a:16:dd:5b:83:de (weave02) [191.235.147.190:6783] Routes: unicast: 7a:f4:56:87:76:3b -> 00:00:00:00:00:00 @@ -86,7 +86,10 @@ The terms used here are explained further at [how it works](how-it-works.html). The 'Our name' line identifies the local weave router as a peer in the -weave network. +weave network, displaying the peer name followed by the peer's nickname +in parenthesis. The nickname defaults to the name of the host on which +the weave container was launched; if desired it can be overriden by +supplying the `-nickname` argument to `weave launch`. The 'Sniffing traffic' line shows details of the virtual ethernet interface that weave is using to receive packets on the local @@ -100,12 +103,13 @@ router last saw some traffic from that MAC. The router forgets addresses which are inactive for longer than 10 minutes. The 'Peers' section lists all peers known to this router, including -itself. Each peer is shown with its name, version number (incremented -on each reconnect) and the UID. Then each line beginning `->` shows -another peer that it is connected to, with the IP address and port -number of the connection. In the above example, the local router has -connected to its peer using address 191.235.147.190:6783, and its peer -sees the same connection as coming from 37.157.33.76:7195. +itself. Each peer is shown with its name, nickname, version number +(incremented on each reconnect) and the UID. Then each line +beginning `->` shows another peer that it is connected to, with the +IP address and port number of the connection. In the above example, +the local router has connected to its peer using address +191.235.147.190:6783, and its peer sees the same connection as coming +from 37.157.33.76:7195. The 'Routes' section summarised the information for deciding how to route packets between peers, which is mostly of interest when the diff --git a/weave b/weave index e3f4540c..e7777274 100755 --- a/weave +++ b/weave @@ -6,7 +6,7 @@ SCRIPT_VERSION="(unreleased version)" usage() { echo "Usage:" echo "weave setup" - echo "weave launch [-password ] ..." + echo "weave launch [-password ] [-nickname ] ..." echo "weave launch-dns " echo "weave connect " echo "weave run [--with-dns] ..." @@ -475,18 +475,31 @@ case "$COMMAND" in echo "WARNING: $1 parameter ignored; 'weave launch' no longer takes a CIDR as the first parameter" >&2 shift 1 fi - if [ "$1" = "-password" ] ; then - [ $# -gt 1 ] || usage - WEAVE_PASSWORD="$2" - export WEAVE_PASSWORD - shift 2 - fi + NICKNAME=$(hostname) + while true; do + case "$1" in + -password) + [ $# -gt 1 ] || usage + WEAVE_PASSWORD="$2" + export WEAVE_PASSWORD + shift 2 + ;; + -nickname) + [ $# -gt 1 ] || usage + NICKNAME="$2" + shift 2 + ;; + *) + break + ;; + esac + done # Set WEAVE_DOCKER_ARGS in the environment in order to supply # additional parameters, such as resource limits, to docker # when launching the weave container. CONTAINER=$(docker run --privileged -d --name=$CONTAINER_NAME \ -p $PORT:$PORT/tcp -p $PORT:$PORT/udp -e WEAVE_PASSWORD \ - $WEAVE_DOCKER_ARGS $IMAGE -name $MACADDR -iface $CONTAINER_IFNAME "$@") + $WEAVE_DOCKER_ARGS $IMAGE -iface $CONTAINER_IFNAME -name $MACADDR -nickname "$NICKNAME" "$@") with_container_netns $CONTAINER launch >/dev/null echo $CONTAINER ;; diff --git a/weaver/main.go b/weaver/main.go index 7d3aae93..da9c5836 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -37,6 +37,7 @@ func main() { justVersion bool ifaceName string routerName string + nickName string password string wait int debug bool @@ -49,6 +50,7 @@ func main() { flag.BoolVar(&justVersion, "version", false, "print version and exit") flag.StringVar(&ifaceName, "iface", "", "name of interface to read from") flag.StringVar(&routerName, "name", "", "name of router (defaults to MAC)") + flag.StringVar(&nickName, "nickname", "", "nickname of peer (defaults to hostname)") flag.StringVar(&password, "password", "", "network password") flag.IntVar(&wait, "wait", 0, "number of seconds to wait for interface to be created and come up (defaults to 0, i.e. don't wait)") flag.BoolVar(&debug, "debug", false, "enable debug logging") @@ -87,6 +89,13 @@ func main() { routerName = iface.HardwareAddr.String() } + if nickName == "" { + nickName, err = os.Hostname() + if err != nil { + log.Fatal(err) + } + } + ourName, err := weave.PeerNameFromUserInput(routerName) if err != nil { log.Fatal(err) @@ -121,8 +130,8 @@ func main() { defer profile.Start(&p).Stop() } - router := weave.NewRouter(iface, ourName, []byte(password), connLimit, bufSz*1024*1024, logFrame) - log.Println("Our name is", router.Ourself.Name) + router := weave.NewRouter(iface, ourName, nickName, []byte(password), connLimit, bufSz*1024*1024, logFrame) + log.Println("Our name is", router.Ourself.Name, "("+router.Ourself.NickName+")") router.Start() for _, peer := range peers { if addr, err := net.ResolveTCPAddr("tcp4", weave.NormalisePeerAddr(peer)); err == nil {