Skip to content

Commit

Permalink
obfs4: Alter tear down behavior to be less distinctive
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Yawning committed Jun 21, 2019
1 parent a828843 commit 1a6129b
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 17 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
26 changes: 9 additions & 17 deletions transports/obfs4/obfs4.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import (
"crypto/sha256"
"flag"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net"
"strconv"
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -233,8 +234,7 @@ type obfs4ServerFactory struct {
iatMode int
replayFilter *replayfilter.ReplayFilter

closeDelayBytes int
closeDelay int
closeDelay int
}

func (sf *obfs4ServerFactory) Transport() base.Transport {
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 1a6129b

Please sign in to comment.