cloudflare/cloudflared
Publicmirrored fromhttps://github.com/cloudflare/cloudflaredAvailable
connection/dial.go
54lines · modecode
| 1 | package connection |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "crypto/tls" |
| 6 | "net" |
| 7 | "time" |
| 8 | |
| 9 | "github.com/pkg/errors" |
| 10 | ) |
| 11 | |
| 12 | // DialEdge makes a TLS connection to a Cloudflare edge node |
| 13 | func DialEdge( |
| 14 | ctx context.Context, |
| 15 | timeout time.Duration, |
| 16 | tlsConfig *tls.Config, |
| 17 | edgeTCPAddr *net.TCPAddr, |
| 18 | ) (net.Conn, error) { |
| 19 | // Inherit from parent context so we can cancel (Ctrl-C) while dialing |
| 20 | dialCtx, dialCancel := context.WithTimeout(ctx, timeout) |
| 21 | defer dialCancel() |
| 22 | |
| 23 | dialer := net.Dialer{} |
| 24 | edgeConn, err := dialer.DialContext(dialCtx, "tcp", edgeTCPAddr.String()) |
| 25 | if err != nil { |
| 26 | return nil, newDialError(err, "DialContext error") |
| 27 | } |
| 28 | tlsEdgeConn := tls.Client(edgeConn, tlsConfig) |
| 29 | tlsEdgeConn.SetDeadline(time.Now().Add(timeout)) |
| 30 | |
| 31 | if err = tlsEdgeConn.Handshake(); err != nil { |
| 32 | return nil, newDialError(err, "TLS handshake with edge error") |
| 33 | } |
| 34 | // clear the deadline on the conn; h2mux has its own timeouts |
| 35 | tlsEdgeConn.SetDeadline(time.Time{}) |
| 36 | return tlsEdgeConn, nil |
| 37 | } |
| 38 | |
| 39 | // DialError is an error returned from DialEdge |
| 40 | type DialError struct { |
| 41 | cause error |
| 42 | } |
| 43 | |
| 44 | func newDialError(err error, message string) error { |
| 45 | return DialError{cause: errors.Wrap(err, message)} |
| 46 | } |
| 47 | |
| 48 | func (e DialError) Error() string { |
| 49 | return e.cause.Error() |
| 50 | } |
| 51 | |
| 52 | func (e DialError) Cause() error { |
| 53 | return e.cause |
| 54 | } |
| 55 | |