Skip to content

Commit

Permalink
Version 2 protocol, which encrypts the features map
Browse files Browse the repository at this point in the history
With V1 compatibility
  • Loading branch information
dpw committed Jul 8, 2015
1 parent 7d5e6b5 commit d7fd3ea
Show file tree
Hide file tree
Showing 6 changed files with 490 additions and 212 deletions.
98 changes: 95 additions & 3 deletions router/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/binary"
"fmt"
"net"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -117,6 +118,7 @@ func StartLocalConnection(connRemote *RemoteConnection, tcpConn *net.TCPConn, ud
TCPConn: tcpConn,
remoteUDPAddr: udpAddr,
effectivePMTU: DefaultPMTU,
uid: randUint64(),
actionChan: actionChan,
finished: finished}
go conn.run(actionChan, finished, acceptNewPeer)
Expand Down Expand Up @@ -282,8 +284,21 @@ func (conn *LocalConnection) run(actionChan <-chan ConnectionAction, finished ch
defer close(finished)

conn.TCPConn.SetLinger(0)
intro, err := ProtocolIntroParams{
Features: conn.makeFeatures(),
Conn: conn.TCPConn,
Password: conn.Router.Password,
Outbound: conn.outbound,
}.DoIntro()
if err != nil {
return
}

tcpReceiver, remote, err := conn.handshake()
conn.SessionKey = intro.SessionKey
conn.tcpSender = intro.Sender
conn.version = intro.Version

remote, err := conn.parseFeatures(intro.Features)
if err != nil {
return
}
Expand All @@ -292,7 +307,13 @@ func (conn *LocalConnection) run(actionChan <-chan ConnectionAction, finished ch
return
}

conn.Log("completed handshake; using protocol version", conn.version)
if conn.SessionKey == nil {
conn.Decryptor = NewNonDecryptor()
} else {
conn.Decryptor = NewNaClDecryptor(conn.SessionKey, conn.outbound)
}

conn.Log("connection ready; using protocol version", conn.version)

// The ordering of the following is very important. [1]

Expand All @@ -307,7 +328,8 @@ func (conn *LocalConnection) run(actionChan <-chan ConnectionAction, finished ch
if err = conn.initHeartbeats(); err != nil {
return
}
go conn.receiveTCP(tcpReceiver)

go conn.receiveTCP(intro.Receiver)
err = conn.actorLoop(actionChan)
}

Expand Down Expand Up @@ -356,6 +378,76 @@ func (conn *LocalConnection) run(actionChan <-chan ConnectionAction, finished ch
// prevent that completely, since, for example, forwarder can only be
// created when we know the remote UDP address, but it helps to try.

func (conn *LocalConnection) makeFeatures() map[string]string {
return map[string]string{
"PeerNameFlavour": PeerNameFlavour,
"Name": conn.local.Name.String(),
"NickName": conn.local.NickName,
"UID": fmt.Sprint(conn.local.UID),
"ConnID": fmt.Sprint(conn.uid),
}
}

type features map[string]string

func (features features) Get(key string) (string, error) {
val, ok := features[key]
if !ok {
return "", fmt.Errorf("Field %s is missing", key)
}

return val, nil
}

func (conn *LocalConnection) parseFeatures(features features) (*Peer, error) {
str, err := features.Get("PeerNameFlavour")
if err != nil {
return nil, err
}

if str != PeerNameFlavour {
return nil, fmt.Errorf("Peer name flavour mismatch (ours: \"%s\", theirs: \"%s\")", PeerNameFlavour, str)
}

str, err = features.Get("Name")
if err != nil {
return nil, err
}

name, err := PeerNameFromString(str)
if err != nil {
return nil, err
}

nickName, err := features.Get("NickName")
if err != nil {
return nil, err
}

str, err = features.Get("UID")
if err != nil {
return nil, err
}

uid, err := ParsePeerUID(str)
if err != nil {
return nil, err
}

str, err = features.Get("ConnID")
if err != nil {
return nil, err
}

remoteConnID, err := strconv.ParseUint(str, 10, 64)
if err != nil {
return nil, err
}

conn.uid ^= remoteConnID
return NewPeer(name, nickName, uid, 0), nil
}

func (conn *LocalConnection) registerRemote(remote *Peer, acceptNewPeer bool) error {
if acceptNewPeer {
conn.remote = conn.Router.Peers.FetchWithDefault(remote)
Expand Down
1 change: 0 additions & 1 deletion router/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const (
PMTUVerifyTimeout = 10 * time.Millisecond // gets doubled with every attempt
MaxDuration = time.Duration(math.MaxInt64)
MaxMissedHeartbeats = 6
HeaderTimeout = 10 * time.Second
HeartbeatTimeout = MaxMissedHeartbeats * SlowHeartbeat
)

Expand Down
148 changes: 0 additions & 148 deletions router/handshake.go

This file was deleted.

30 changes: 0 additions & 30 deletions router/handshake_test.go

This file was deleted.

Loading

0 comments on commit d7fd3ea

Please sign in to comment.