summaryrefslogtreecommitdiff
path: root/dialer.go
diff options
context:
space:
mode:
Diffstat (limited to 'dialer.go')
-rw-r--r--dialer.go57
1 files changed, 57 insertions, 0 deletions
diff --git a/dialer.go b/dialer.go
new file mode 100644
index 0000000..0c3f8c3
--- /dev/null
+++ b/dialer.go
@@ -0,0 +1,57 @@
+package obfsvpn
+
+import (
+ "context"
+ "net"
+ "strconv"
+
+ pt "git.torproject.org/pluggable-transports/goptlib.git"
+ "gitlab.com/yawning/obfs4.git/common/ntor"
+ "gitlab.com/yawning/obfs4.git/transports/base"
+ "gitlab.com/yawning/obfs4.git/transports/obfs4"
+)
+
+// IATMode determines the amount of time sent between packets.
+type IATMode int
+
+// Valid IAT modes.
+const (
+ IATNone IATMode = iota
+ IATEnabled
+ IATParanoid
+)
+
+// Dialer contains options for connecting to an address and obfuscating traffic
+// with the obfs4 protocol.
+// It performs the ntor handshake on all dialed connections.
+type Dialer struct {
+ Dialer net.Dialer
+
+ NodeID *ntor.NodeID
+ PublicKey *ntor.PublicKey
+ IATMode IATMode
+
+ cf base.ClientFactory
+}
+
+// Dial creates an outbound net.Conn and performs the ntor handshake.
+func (d *Dialer) Dial(ctx context.Context, network, address string) (net.Conn, error) {
+ if d.cf == nil {
+ cf, err := (&obfs4.Transport{}).ClientFactory("")
+ if err != nil {
+ return nil, err
+ }
+ d.cf = cf
+ }
+ ptArgs := make(pt.Args)
+ ptArgs.Add("node-id", d.NodeID.Hex())
+ ptArgs.Add("public-key", d.PublicKey.Hex())
+ ptArgs.Add("iat-mode", strconv.Itoa(int(d.IATMode)))
+ args, err := d.cf.ParseArgs(&ptArgs)
+ if err != nil {
+ return nil, err
+ }
+ return d.cf.Dial(network, address, func(network, address string) (net.Conn, error) {
+ return d.Dialer.DialContext(ctx, network, address)
+ }, args)
+}