diff options
author | Sam Whited <sam@samwhited.com> | 2022-03-08 10:45:53 -0500 |
---|---|---|
committer | Sam Whited <sam@samwhited.com> | 2022-03-08 10:45:53 -0500 |
commit | b15033d1e22567d0ce50e64c0ddb8247c004d372 (patch) | |
tree | 52882161ec44f1bbfbd955992c75a2cdbf42e7ab | |
parent | 17b86c8624b4f791e9d20fc6c56da36fd456a93b (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.go | 57 |
1 files changed, 52 insertions, 5 deletions
@@ -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 +} |