@@ -28,16 +28,19 @@ type ServerInstance struct {
2828 Hash32s [][32 ]byte
2929 RelaysLength int
3030 XorMode uint32
31- SecondsFrom uint32
32- SecondsTo uint32
31+ SecondsFrom int64
32+ SecondsTo int64
3333 PaddingLens [][3 ]int
3434 PaddingGaps [][3 ]int
3535
3636 RWLock sync.RWMutex
37+ Closed bool
38+ Lasts map [int64 ][16 ]byte
39+ Tickets [][16 ]byte
3740 Sessions map [[16 ]byte ]* ServerSession
3841}
3942
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 ) {
4144 if i .NfsSKeys != nil {
4245 return errors .New ("already initialized" )
4346 }
@@ -68,8 +71,47 @@ func (i *ServerInstance) Init(nfsSKeysBytes [][]byte, xorMode, secondsFrom, seco
6871 i .XorMode = xorMode
6972 i .SecondsFrom = secondsFrom
7073 i .SecondsTo = secondsTo
71- i .Sessions = make (map [[16 ]byte ]* ServerSession )
72- return ParsePadding (padding , & i .PaddingLens , & i .PaddingGaps )
74+ err = ParsePadding (padding , & i .PaddingLens , & i .PaddingGaps )
75+ if err != nil {
76+ return
77+ }
78+ if i .SecondsFrom > 0 || i .SecondsTo > 0 {
79+ i .Lasts = make (map [int64 ][16 ]byte )
80+ i .Tickets = make ([][16 ]byte , 0 , 1024 )
81+ i .Sessions = make (map [[16 ]byte ]* ServerSession )
82+ go func () {
83+ for {
84+ time .Sleep (time .Minute )
85+ i .RWLock .Lock ()
86+ if i .Closed {
87+ i .RWLock .Unlock ()
88+ return
89+ }
90+ minute := time .Now ().Unix () / 60
91+ last := i .Lasts [minute ]
92+ delete (i .Lasts , minute )
93+ delete (i .Lasts , minute - 1 ) // for insurance
94+ if last != [16 ]byte {} {
95+ for j , ticket := range i .Tickets {
96+ delete (i .Sessions , ticket )
97+ if ticket == last {
98+ i .Tickets = i .Tickets [j + 1 :]
99+ break
100+ }
101+ }
102+ }
103+ i .RWLock .Unlock ()
104+ }
105+ }()
106+ }
107+ return
108+ }
109+
110+ func (i * ServerInstance ) Close () (err error ) {
111+ i .RWLock .Lock ()
112+ i .Closed = true
113+ i .RWLock .Unlock ()
114+ return
73115}
74116
75117func (i * ServerInstance ) Handshake (conn net.Conn , fallback * []byte ) (* CommonConn , error ) {
@@ -224,33 +266,29 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn
224266 c .AEAD = NewAEAD (pfsPublicKey , c .UnitedKey , c .UseAES )
225267 c .PeerAEAD = NewAEAD (encryptedPfsPublicKey [:1184 + 32 ], c .UnitedKey , c .UseAES )
226268
227- ticket := make ([ ]byte , 16 )
228- rand .Read (ticket )
229- seconds := 0
269+ ticket := [ 16 ]byte {}
270+ rand .Read (ticket [:] )
271+ var seconds int64
230272 if i .SecondsTo == 0 {
231- seconds = int ( i .SecondsFrom ) * int ( crypto .RandBetween (50 , 100 ) ) / 100
273+ seconds = i .SecondsFrom * crypto .RandBetween (50 , 100 ) / 100
232274 } else {
233- seconds = int ( crypto .RandBetween (int64 ( i .SecondsFrom ), int64 ( i .SecondsTo )) )
275+ seconds = crypto .RandBetween (i .SecondsFrom , i .SecondsTo )
234276 }
235- copy (ticket , EncodeLength (int (seconds )))
277+ copy (ticket [:] , EncodeLength (int (seconds )))
236278 if seconds > 0 {
237279 i .RWLock .Lock ()
238- i .Sessions [[16 ]byte (ticket )] = & ServerSession {PfsKey : pfsKey }
280+ i .Lasts [(time .Now ().Unix ()+ max (i .SecondsFrom , i .SecondsTo ))/ 60 + 2 ] = ticket
281+ i .Tickets = append (i .Tickets , ticket )
282+ i .Sessions [ticket ] = & ServerSession {PfsKey : pfsKey }
239283 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- }()
246284 }
247285
248286 pfsKeyExchangeLength := 1088 + 32 + 16
249287 encryptedTicketLength := 32
250288 paddingLength , paddingLens , paddingGaps := CreatPadding (i .PaddingLens , i .PaddingGaps )
251289 serverHello := make ([]byte , pfsKeyExchangeLength + encryptedTicketLength + paddingLength )
252290 nfsAEAD .Seal (serverHello [:0 ], MaxNonce , pfsPublicKey , nil )
253- c .AEAD .Seal (serverHello [:pfsKeyExchangeLength ], nil , ticket , nil )
291+ c .AEAD .Seal (serverHello [:pfsKeyExchangeLength ], nil , ticket [:] , nil )
254292 padding := serverHello [pfsKeyExchangeLength + encryptedTicketLength :]
255293 c .AEAD .Seal (padding [:0 ], nil , EncodeLength (paddingLength - 18 ), nil )
256294 c .AEAD .Seal (padding [:18 ], nil , padding [18 :paddingLength - 16 ], nil )
@@ -284,7 +322,7 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn
284322 }
285323
286324 if i .XorMode == 2 {
287- c .Conn = NewXorConn (conn , NewCTR (c .UnitedKey , ticket ), NewCTR (c .UnitedKey , iv ), 0 , 0 )
325+ c .Conn = NewXorConn (conn , NewCTR (c .UnitedKey , ticket [:] ), NewCTR (c .UnitedKey , iv ), 0 , 0 )
288326 }
289327 return c , nil
290328}
0 commit comments