~samwhited/xmpp

ref: d3ceddb51fa198df1449016fda7923afe83bb0f3 xmpp/dial.go -rw-r--r-- 4.1 KiB
d3ceddb5Sam Whited Add some new options to Config 5 years ago
                                                                                
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright 2016 Sam Whited.
// Use of this source code is governed by the BSD 2-clause license that can be
// found in the LICENSE file.

package xmpp

import (
	"net"
	"time"

	"golang.org/x/net/context"
	"mellium.im/xmpp/jid"
)

// DialClient discovers and connects to the address on the named network that
// services the given local address with a client-to-server (c2s) connection.
//
// laddr is the clients origin address. The remote address is taken from the
// origins domain part or from the domains SRV records. For a description of the
// ctx and network arguments, see the Dial function.
func DialClient(ctx context.Context, network string, laddr *jid.JID) (*Conn, error) {
	var d Dialer
	return d.DialClient(ctx, network, laddr)
}

// DialServer connects to the address on the named network with a
// server-to-server (s2s) connection.
//
// raddr is the remote servers address and laddr is the local servers origin
// address. For a description of the ctx and network arguments, see the Dial
// function.
func DialServer(ctx context.Context, network string, raddr, laddr *jid.JID) (*Conn, error) {
	var d Dialer
	return d.DialServer(ctx, network, raddr, laddr)
}

// Dial connects to the address on the named network using the provided config.
//
// The context must be non-nil. If the context expires before the connection is
// complete, an error is returned. Once successfully connected, any expiration
// of the context will not affect the connection.
//
// Network may be any of the network types supported by net.Dial, but you almost
// certainly want to use one of the tcp connection types ("tcp", "tcp4", or
// "tcp6").
func Dial(ctx context.Context, network string, config *Config) (*Conn, error) {
	var d Dialer
	return d.Dial(ctx, network, config)
}

// A Dialer contains options for connecting to an XMPP address.
//
// The zero value for each field is equivalent to dialing without that option.
// Dialing with the zero value of Dialer is therefore equivalent to just calling
// the DialClient function.
type Dialer struct {
	net.Dialer

	// NoLookup stops the dialer from looking up SRV or TXT records for the given
	// domain. It also prevents fetching of the host metadata file.
	// Instead, it will try to connect to the domain directly.
	NoLookup bool
}

// Copied from the net package in the standard library. Copyright The Go
// Authors.
func minNonzeroTime(a, b time.Time) time.Time {
	if a.IsZero() {
		return b
	}
	if b.IsZero() || a.Before(b) {
		return a
	}
	return b
}

// Copied from the net package in the standard library. Copyright The Go
// Authors.
//
// deadline returns the earliest of:
//   - now+Timeout
//   - d.Deadline
//   - the context's deadline
// Or zero, if none of Timeout, Deadline, or context's deadline is set.
func (d *Dialer) deadline(ctx context.Context, now time.Time) (earliest time.Time) {
	if d.Timeout != 0 { // including negative, for historical reasons
		earliest = now.Add(d.Timeout)
	}
	if d, ok := ctx.Deadline(); ok {
		earliest = minNonzeroTime(earliest, d)
	}
	return minNonzeroTime(earliest, d.Deadline)
}

// DialClient discovers and connects to the address on the named network that
// services the given local address with a client-to-server (c2s) connection.
//
// For a description of the arguments see the DialClient function.
func (d *Dialer) DialClient(ctx context.Context, network string, laddr *jid.JID) (*Conn, error) {
	c := NewClientConfig(laddr)
	return d.Dial(ctx, network, c)
}

// DialServer connects to the address on the named network with a
// server-to-server (s2s) connection.
//
// For a description of the arguments see the DialServer function.
func (d *Dialer) DialServer(ctx context.Context, network string, raddr, laddr *jid.JID) (*Conn, error) {
	c := NewServerConfig(raddr, laddr)
	return d.Dial(ctx, network, c)
}

// Dial connects to the address on the named network using the provided config.
//
// For a description of the arguments see the Dial function.
func (d *Dialer) Dial(
	ctx context.Context, network string, config *Config) (*Conn, error) {
	c, err := d.dial(ctx, network, config)
	if err != nil {
		return c, err
	}
	c.connect(ctx)

	return c, err
}