obfs4: Alter tear down behavior to be less distinctive

The old behavior closed the connection on handshake failure after:
 * The first N bytes (random on a per-server basis).
 * The first M seconds (random on a per-server basis).

Whichever came first.  As Sergey Frolov kindly points out, depending on
which conditions cause termination, the server will send either a FIN or
a RST.  This change will remove the "amount read" based termination
threshold, so that connections that cause failed handshakes will discard
all data received until the teardown time is reached.

Thanks to Sergey Frolov for bringing this issue to my attention.
merge-requests/3/head
Yawning Angel 5 years ago
parent a8288437e3
commit 1a6129b66f

@ -1,5 +1,7 @@
Changes in version 0.0.11 - UNRELEASED:
- Update my e-mail address.
- Change the obfs4 behavior for handling handshake failure to be more
uniform. Thanks to Sergey Frolov for assistance.
Changes in version 0.0.10 - 2019-04-12:
- Disable behavior distinctive to crypto/tls when using utls.

@ -34,6 +34,8 @@ import (
"crypto/sha256"
"flag"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net"
"strconv"
@ -67,9 +69,8 @@ const (
serverHandshakeTimeout = time.Duration(30) * time.Second
replayTTL = time.Duration(3) * time.Hour
maxIATDelay = 100
maxCloseDelayBytes = maxHandshakeLength
maxCloseDelay = 60
maxIATDelay = 100
maxCloseDelay = 60
)
const (
@ -138,7 +139,7 @@ func (t *Transport) ServerFactory(stateDir string, args *pt.Args) (base.ServerFa
}
rng := rand.New(drbg)
sf := &obfs4ServerFactory{t, &ptArgs, st.nodeID, st.identityKey, st.drbgSeed, iatSeed, st.iatMode, filter, rng.Intn(maxCloseDelayBytes), rng.Intn(maxCloseDelay)}
sf := &obfs4ServerFactory{t, &ptArgs, st.nodeID, st.identityKey, st.drbgSeed, iatSeed, st.iatMode, filter, rng.Intn(maxCloseDelay)}
return sf, nil
}
@ -233,8 +234,7 @@ type obfs4ServerFactory struct {
iatMode int
replayFilter *replayfilter.ReplayFilter
closeDelayBytes int
closeDelay int
closeDelay int
}
func (sf *obfs4ServerFactory) Transport() base.Transport {
@ -592,17 +592,9 @@ func (conn *obfs4Conn) closeAfterDelay(sf *obfs4ServerFactory, startTime time.Ti
return
}
// Consume and discard data on this connection until either the specified
// interval passes or a certain size has been reached.
discarded := 0
var buf [framing.MaximumSegmentLength]byte
for discarded < int(sf.closeDelayBytes) {
n, err := conn.Conn.Read(buf[:])
if err != nil {
return
}
discarded += n
}
// Consume and discard data on this connection until the specified interval
// passes.
_, _ = io.Copy(ioutil.Discard, conn.Conn)
}
func (conn *obfs4Conn) padBurst(burst *bytes.Buffer, toPadTo int) (err error) {

Loading…
Cancel
Save