-
Notifications
You must be signed in to change notification settings - Fork 1
/
hop.go
59 lines (46 loc) · 1.17 KB
/
hop.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package tunnel
import (
"errors"
"fmt"
"regexp"
"strconv"
"golang.org/x/crypto/ssh"
)
// hop represents a hop in the tunnel
type hop struct {
username string
host string
port int
sshClientConfig ssh.ClientConfig
sshClient *ssh.Client
}
// userHostPortRegex matches username@host:port
var userHostPortRegex = regexp.MustCompile(`^([^@]+)@([^:]+):(\d+)`)
// errors
var (
ErrInvalidFormat = errors.New("invalid format")
)
// parseHops just parses the list of hop specs and returns an array of hop elements.
func parseHops(userHostPorts []string) ([]hop, error) {
var links []hop
for _, s := range userHostPorts {
uhp := userHostPortRegex.FindStringSubmatch(s)
if len(uhp) != 4 {
return nil, fmt.Errorf("%w: wrong number of elements in [%s]", ErrInvalidFormat, s)
}
port, err := strconv.ParseInt(uhp[3], 10, 64)
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrInvalidFormat, err)
}
link := hop{
username: uhp[1],
host: uhp[2],
port: int(port),
}
links = append(links, link)
}
return links, nil
}
func (l hop) String() string {
return fmt.Sprintf("%s@%s:%d", l.username, l.host, l.port)
}