summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Whited <sam@samwhited.com>2022-03-08 10:45:53 -0500
committerSam Whited <sam@samwhited.com>2022-03-08 10:45:53 -0500
commitb15033d1e22567d0ce50e64c0ddb8247c004d372 (patch)
tree52882161ec44f1bbfbd955992c75a2cdbf42e7ab
parent17b86c8624b4f791e9d20fc6c56da36fd456a93b (diff)
obfsvpn: create new dialer from PT args
The dialer is meant as a way to avoid having to use or think about pluggable transport arguments (you can provide them all as typed configurations on the dialer), however, sometimes we already have the pluggable transport arguments in their parsed form (eg. when using a higher level protocol to negotiate the args) and need to construct a dialer from them. This patch allows constructing the dialer and getting the original arguments back out. Signed-off-by: Sam Whited <sam@samwhited.com>
-rw-r--r--dialer.go57
1 files changed, 52 insertions, 5 deletions
diff --git a/dialer.go b/dialer.go
index 0c3f8c3..a7bd075 100644
--- a/dialer.go
+++ b/dialer.go
@@ -2,6 +2,7 @@ package obfsvpn
import (
"context"
+ "fmt"
"net"
"strconv"
@@ -11,6 +12,12 @@ import (
"gitlab.com/yawning/obfs4.git/transports/obfs4"
)
+const (
+ ptArgNode = "node-id"
+ ptArgKey = "public-key"
+ ptArgMode = "iat-mode"
+)
+
// IATMode determines the amount of time sent between packets.
type IATMode int
@@ -31,7 +38,39 @@ type Dialer struct {
PublicKey *ntor.PublicKey
IATMode IATMode
- cf base.ClientFactory
+ ptArgs pt.Args
+ cf base.ClientFactory
+}
+
+// NewDialer creates a dialer from existing pluggable transport arguments.
+func NewDialer(args pt.Args) (*Dialer, error) {
+ cf, err := (&obfs4.Transport{}).ClientFactory("")
+ if err != nil {
+ return nil, err
+ }
+ nodeHex, _ := args.Get(ptArgNode)
+ node, err := ntor.NodeIDFromHex(nodeHex)
+ if err != nil {
+ return nil, err
+ }
+ keyHex, _ := args.Get(ptArgKey)
+ pub, err := ntor.PublicKeyFromHex(keyHex)
+ if err != nil {
+ return nil, err
+ }
+ iatModeStr, _ := args.Get(ptArgMode)
+ iatMode, err := strconv.Atoi(iatModeStr)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing IAT mode to integer: %w", err)
+ }
+ return &Dialer{
+ NodeID: node,
+ PublicKey: pub,
+ IATMode: IATMode(iatMode),
+
+ ptArgs: args,
+ cf: cf,
+ }, nil
}
// Dial creates an outbound net.Conn and performs the ntor handshake.
@@ -43,10 +82,7 @@ func (d *Dialer) Dial(ctx context.Context, network, address string) (net.Conn, e
}
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)))
+ ptArgs := d.Args()
args, err := d.cf.ParseArgs(&ptArgs)
if err != nil {
return nil, err
@@ -55,3 +91,14 @@ func (d *Dialer) Dial(ctx context.Context, network, address string) (net.Conn, e
return d.Dialer.DialContext(ctx, network, address)
}, args)
}
+
+// Args returns the dialers options as pluggable transport arguments.
+func (d *Dialer) Args() pt.Args {
+ if d.ptArgs == nil {
+ d.ptArgs = make(pt.Args)
+ d.ptArgs.Add(ptArgNode, d.NodeID.Hex())
+ d.ptArgs.Add(ptArgKey, d.PublicKey.Hex())
+ d.ptArgs.Add(ptArgMode, strconv.Itoa(int(d.IATMode)))
+ }
+ return d.ptArgs
+}