@@ -28,16 +28,19 @@ type ServerInstance struct {
28
28
Hash32s [][32 ]byte
29
29
RelaysLength int
30
30
XorMode uint32
31
- SecondsFrom uint32
32
- SecondsTo uint32
31
+ SecondsFrom int64
32
+ SecondsTo int64
33
33
PaddingLens [][3 ]int
34
34
PaddingGaps [][3 ]int
35
35
36
36
RWLock sync.RWMutex
37
+ Closed bool
38
+ Lasts map [int64 ][16 ]byte
39
+ Tickets [][16 ]byte
37
40
Sessions map [[16 ]byte ]* ServerSession
38
41
}
39
42
40
- func (i * ServerInstance ) Init (nfsSKeysBytes [][]byte , xorMode , secondsFrom , secondsTo uint32 , padding string ) (err error ) {
43
+ func (i * ServerInstance ) Init (nfsSKeysBytes [][]byte , xorMode uint32 , secondsFrom , secondsTo int64 , padding string ) (err error ) {
41
44
if i .NfsSKeys != nil {
42
45
return errors .New ("already initialized" )
43
46
}
@@ -68,10 +71,45 @@ func (i *ServerInstance) Init(nfsSKeysBytes [][]byte, xorMode, secondsFrom, seco
68
71
i .XorMode = xorMode
69
72
i .SecondsFrom = secondsFrom
70
73
i .SecondsTo = secondsTo
71
- i .Sessions = make (map [[16 ]byte ]* ServerSession )
74
+ if i .SecondsFrom > 0 || i .SecondsTo > 0 {
75
+ i .Lasts = make (map [int64 ][16 ]byte )
76
+ i .Tickets = make ([][16 ]byte , 0 , 1024 )
77
+ i .Sessions = make (map [[16 ]byte ]* ServerSession )
78
+ go func () {
79
+ for {
80
+ time .Sleep (time .Minute )
81
+ i .RWLock .Lock ()
82
+ if i .Closed {
83
+ i .RWLock .Unlock ()
84
+ return
85
+ }
86
+ minute := time .Now ().Unix () / 60
87
+ last := i .Lasts [minute ]
88
+ delete (i .Lasts , minute )
89
+ delete (i .Lasts , minute - 1 ) // for insurance
90
+ if last != [16 ]byte {} {
91
+ for j , ticket := range i .Tickets {
92
+ delete (i .Sessions , ticket )
93
+ if ticket == last {
94
+ i .Tickets = i .Tickets [j + 1 :]
95
+ break
96
+ }
97
+ }
98
+ }
99
+ i .RWLock .Unlock ()
100
+ }
101
+ }()
102
+ }
72
103
return ParsePadding (padding , & i .PaddingLens , & i .PaddingGaps )
73
104
}
74
105
106
+ func (i * ServerInstance ) Close () (err error ) {
107
+ i .RWLock .Lock ()
108
+ i .Closed = true
109
+ i .RWLock .Unlock ()
110
+ return
111
+ }
112
+
75
113
func (i * ServerInstance ) Handshake (conn net.Conn , fallback * []byte ) (* CommonConn , error ) {
76
114
if i .NfsSKeys == nil {
77
115
return nil , errors .New ("uninitialized" )
@@ -224,33 +262,29 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn
224
262
c .AEAD = NewAEAD (pfsPublicKey , c .UnitedKey , c .UseAES )
225
263
c .PeerAEAD = NewAEAD (encryptedPfsPublicKey [:1184 + 32 ], c .UnitedKey , c .UseAES )
226
264
227
- ticket := make ([ ]byte , 16 )
228
- rand .Read (ticket )
229
- seconds := 0
265
+ ticket := [ 16 ]byte {}
266
+ rand .Read (ticket [:] )
267
+ var seconds int64
230
268
if i .SecondsTo == 0 {
231
- seconds = int ( i .SecondsFrom ) * int ( crypto .RandBetween (50 , 100 ) ) / 100
269
+ seconds = i .SecondsFrom * crypto .RandBetween (50 , 100 ) / 100
232
270
} else {
233
- seconds = int ( crypto .RandBetween (int64 ( i .SecondsFrom ), int64 ( i .SecondsTo )) )
271
+ seconds = crypto .RandBetween (i .SecondsFrom , i .SecondsTo )
234
272
}
235
- copy (ticket , EncodeLength (int (seconds )))
273
+ copy (ticket [:] , EncodeLength (int (seconds )))
236
274
if seconds > 0 {
237
275
i .RWLock .Lock ()
238
- i .Sessions [[16 ]byte (ticket )] = & ServerSession {PfsKey : pfsKey }
276
+ i .Lasts [(time .Now ().Unix ()+ max (i .SecondsFrom , i .SecondsTo ))/ 60 + 2 ] = ticket
277
+ i .Tickets = append (i .Tickets , ticket )
278
+ i .Sessions [ticket ] = & ServerSession {PfsKey : pfsKey }
239
279
i .RWLock .Unlock ()
240
- go func () {
241
- time .Sleep (time .Duration (seconds )* time .Second + time .Minute )
242
- i .RWLock .Lock ()
243
- delete (i .Sessions , [16 ]byte (ticket ))
244
- i .RWLock .Unlock ()
245
- }()
246
280
}
247
281
248
282
pfsKeyExchangeLength := 1088 + 32 + 16
249
283
encryptedTicketLength := 32
250
284
paddingLength , paddingLens , paddingGaps := CreatPadding (i .PaddingLens , i .PaddingGaps )
251
285
serverHello := make ([]byte , pfsKeyExchangeLength + encryptedTicketLength + paddingLength )
252
286
nfsAEAD .Seal (serverHello [:0 ], MaxNonce , pfsPublicKey , nil )
253
- c .AEAD .Seal (serverHello [:pfsKeyExchangeLength ], nil , ticket , nil )
287
+ c .AEAD .Seal (serverHello [:pfsKeyExchangeLength ], nil , ticket [:] , nil )
254
288
padding := serverHello [pfsKeyExchangeLength + encryptedTicketLength :]
255
289
c .AEAD .Seal (padding [:0 ], nil , EncodeLength (paddingLength - 18 ), nil )
256
290
c .AEAD .Seal (padding [:18 ], nil , padding [18 :paddingLength - 16 ], nil )
@@ -284,7 +318,7 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn
284
318
}
285
319
286
320
if i .XorMode == 2 {
287
- c .Conn = NewXorConn (conn , NewCTR (c .UnitedKey , ticket ), NewCTR (c .UnitedKey , iv ), 0 , 0 )
321
+ c .Conn = NewXorConn (conn , NewCTR (c .UnitedKey , ticket [:] ), NewCTR (c .UnitedKey , iv ), 0 , 0 )
288
322
}
289
323
return c , nil
290
324
}
0 commit comments