@@ -57,12 +57,9 @@ func (nd *NetDog) Close() error {
57
57
return nd .dirConn .Close ()
58
58
}
59
59
60
- func ( nd * NetDog ) pick ( needle * [32 ]byte ) * directory.ShortNodeInfo {
60
+ func Pick ( routers [] * directory. ShortNodeInfo , needle * [32 ]byte ) * directory.ShortNodeInfo {
61
61
var highestNotGreater * directory.ShortNodeInfo
62
- for _ , ni := range nd .routers {
63
- if ! ni .Fast || ! ni .Stable || ! ni .Running || ! ni .Valid {
64
- continue
65
- }
62
+ for _ , ni := range routers {
66
63
if bytes .Compare (ni .ID [:], needle [:]) <= 0 &&
67
64
(highestNotGreater == nil || bytes .Compare (ni .ID [:], highestNotGreater .ID [:]) > 0 ) {
68
65
highestNotGreater = ni
@@ -71,11 +68,8 @@ func (nd *NetDog) pick(needle *[32]byte) *directory.ShortNodeInfo {
71
68
if highestNotGreater != nil {
72
69
return highestNotGreater
73
70
}
74
- highestOverall := nd .routers [0 ]
75
- for _ , ni := range nd .routers {
76
- if ! ni .Fast || ! ni .Stable || ! ni .Running {
77
- continue
78
- }
71
+ highestOverall := routers [0 ]
72
+ for _ , ni := range routers {
79
73
if bytes .Compare (ni .ID [:], highestOverall .ID [:]) > 0 {
80
74
highestOverall = ni
81
75
}
@@ -85,45 +79,25 @@ func (nd *NetDog) pick(needle *[32]byte) *directory.ShortNodeInfo {
85
79
86
80
// connect requires len(cookie) = 20 and len(sendPayload) == 148. Nondeterminisitcally, EITHER
87
81
// the sendPayload is sent to the peer OR their sendPayload is returned here, not both.
88
- func connect (ctx context.Context , tc * torch.TorConn , cookie []byte , sendPayload []byte , tcID []byte , tcNtorPublic []byte ) (* torch.TorConn , * torch.Circuit , []byte , error ) {
89
- type circRet struct {
90
- * torch.Circuit
91
- error
92
- }
93
- ch := make (chan circRet )
94
- mkCirc := func () {
95
- circ , err := tc .CreateCircuit (ctx , tcID , tcNtorPublic )
96
- ch <- circRet {circ , err }
97
- }
98
- go mkCirc ()
99
- go mkCirc ()
100
-
101
- cr := <- ch
102
- if cr .error != nil {
103
- <- ch
104
- return nil , nil , nil , cr .error
105
- }
106
- circ := cr .Circuit
107
- accept , err := circ .ListenRendezvousRaw (cookie )
108
- if err == nil {
82
+ func connect (ctx context.Context , c1 , c2 * torch.Circuit , cookie []byte , sendPayload []byte ) (* torch.Circuit , []byte , error ) {
83
+ if accept , err := c1 .ListenRendezvousRaw (cookie ); err == nil {
84
+ c2 .Close ()
85
+
109
86
recvPayload , err := accept ()
110
87
if err != nil {
111
- return nil , nil , nil , err
88
+ c1 .Close ()
89
+ return nil , nil , err
112
90
}
113
- go func () { <- ch ; close (ch ) }()
114
- return tc , circ , recvPayload , nil
115
- }
116
- cr = <- ch
117
- close (ch )
118
- if cr .error != nil {
119
- <- ch
120
- return nil , nil , nil , cr .error
91
+
92
+ return c1 , recvPayload , nil
121
93
}
122
- circ = cr .Circuit
123
- if err := circ .DialRendezvousRaw (cookie , sendPayload ); err != nil {
124
- return nil , nil , nil , err
94
+ c1 .Close ()
95
+
96
+ if err := c2 .DialRendezvousRaw (cookie , sendPayload ); err != nil {
97
+ c2 .Close ()
98
+ return nil , nil , err
125
99
}
126
- return tc , circ , nil , nil
100
+ return c2 , nil , nil
127
101
}
128
102
129
103
func ND (ctx context.Context , needle * [32 ]byte , seed []byte ) (* Conn , error ) {
@@ -133,7 +107,7 @@ func ND(ctx context.Context, needle *[32]byte, seed []byte) (*Conn, error) {
133
107
}
134
108
defer nd .Close ()
135
109
136
- mid_ , err := torch .DownloadMicrodescriptors (nd .dirClient , []* directory.ShortNodeInfo {nd .pick ( needle )})
110
+ mid_ , err := torch .DownloadMicrodescriptors (nd .dirClient , []* directory.ShortNodeInfo {Pick ( nd .routers , needle )})
137
111
if err != nil {
138
112
return nil , err
139
113
}
@@ -147,11 +121,21 @@ func ND(ctx context.Context, needle *[32]byte, seed []byte) (*Conn, error) {
147
121
return nil , err
148
122
}
149
123
150
- return Handshake (ctx , tc , seed , mid .ID [:], mid .NTorOnionKey [:])
124
+ c1 , err := tc .CreateCircuit (ctx , mid .ID [:], mid .NTorOnionKey )
125
+ if err != nil {
126
+ return nil , err
127
+ }
128
+ c2 , err := tc .CreateCircuit (ctx , mid .ID [:], mid .NTorOnionKey )
129
+ if err != nil {
130
+ return nil , err
131
+ }
132
+ return Handshake (ctx , c1 , c2 , seed )
151
133
}
152
134
153
- func Handshake (ctx context.Context , tc * torch.TorConn , seed , routerID , routerNTorPublic []byte ) (* Conn , error ) {
154
- kdf := hkdf .New (sha256 .New , seed , routerID , nil )
135
+ func Handshake (ctx context.Context , c1 , c2 * torch.Circuit , sharedSecret []byte ) (* Conn , error ) {
136
+ // NOTE: one of the circuits is only needed after a couple of network round
137
+ // trips, so it may be a good idea to pass in a <-chan *Circuit instead.
138
+ kdf := hkdf .New (sha256 .New , sharedSecret , nil , nil )
155
139
var cookie [20 ]byte
156
140
var authKeyAccept , authKeyDial , continueKey [32 ]byte
157
141
if _ , err := io .ReadFull (kdf , cookie [:]); err != nil {
@@ -173,7 +157,7 @@ func Handshake(ctx context.Context, tc *torch.TorConn, seed, routerID, routerNTo
173
157
var theirPK [32 ]byte
174
158
vouchDial := secretbox .Seal (nil , pk [:], & [24 ]byte {}, & authKeyDial )
175
159
176
- tc , circ , theirVouchDial , err := connect (ctx , tc , cookie [:], vouchDial [:], routerID , routerNTorPublic )
160
+ circ , theirVouchDial , err := connect (ctx , c1 , c2 , cookie [:], vouchDial [:])
177
161
if err != nil {
178
162
return nil , err
179
163
}
@@ -204,9 +188,8 @@ func Handshake(ctx context.Context, tc *torch.TorConn, seed, routerID, routerNTo
204
188
var sharedDH [32 ]byte
205
189
curve25519 .ScalarMult (& sharedDH , sk , & theirPK )
206
190
ret := & Conn {
207
- TorConn : tc ,
208
191
Circuit : circ ,
209
- KDF : hkdf .New (sha256 .New , append (continueKey [:], sharedDH [:]... ), routerID [:] , nil ),
192
+ KDF : hkdf .New (sha256 .New , append (continueKey [:], sharedDH [:]... ), nil , nil ),
210
193
Bit : theirVouchDial != nil ,
211
194
}
212
195
if ret .Bit {
0 commit comments