2018-02-07 19:32:11 +01:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"encoding/xml"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"strings"
|
2018-02-11 09:07:07 +01:00
|
|
|
"time"
|
2018-02-07 19:32:11 +01:00
|
|
|
|
2018-02-11 22:03:58 +01:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
2018-02-14 18:49:26 +01:00
|
|
|
"dev.sum7.eu/genofire/yaja/xmpp"
|
|
|
|
"dev.sum7.eu/genofire/yaja/xmpp/base"
|
2018-02-07 19:32:11 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Client holds XMPP connection opitons
|
|
|
|
type Client struct {
|
2018-02-11 22:03:58 +01:00
|
|
|
Protocol string // tcp tcp4 tcp6 are supported
|
|
|
|
Timeout time.Duration
|
|
|
|
conn net.Conn // connection to server
|
|
|
|
out *xml.Encoder
|
|
|
|
in *xml.Decoder
|
|
|
|
|
2018-02-22 18:13:17 +01:00
|
|
|
Logging *log.Entry
|
2018-02-07 19:32:11 +01:00
|
|
|
|
2018-02-14 18:49:26 +01:00
|
|
|
JID *xmppbase.JID
|
2018-02-13 20:05:18 +01:00
|
|
|
|
2018-02-22 18:13:17 +01:00
|
|
|
SkipError bool
|
|
|
|
msg chan interface{}
|
|
|
|
reply map[string]chan *xmpp.IQClient
|
2018-02-07 19:32:11 +01:00
|
|
|
}
|
|
|
|
|
2018-02-14 18:49:26 +01:00
|
|
|
func NewClient(jid *xmppbase.JID, password string) (*Client, error) {
|
2018-02-11 22:03:58 +01:00
|
|
|
client := &Client{
|
|
|
|
Protocol: "tcp",
|
|
|
|
JID: jid,
|
2018-02-22 18:13:17 +01:00
|
|
|
Logging: log.New().WithField("jid", jid.String()),
|
2018-02-11 22:03:58 +01:00
|
|
|
}
|
|
|
|
return client, client.Connect(password)
|
2018-02-11 09:07:07 +01:00
|
|
|
|
2018-02-11 22:03:58 +01:00
|
|
|
}
|
|
|
|
func (client *Client) Connect(password string) error {
|
|
|
|
_, srvEntries, err := net.LookupSRV("xmpp-client", "tcp", client.JID.Domain)
|
|
|
|
addr := client.JID.Domain + ":5222"
|
2018-02-10 13:34:42 +01:00
|
|
|
if err == nil && len(srvEntries) > 0 {
|
|
|
|
bestSrv := srvEntries[0]
|
|
|
|
for _, srv := range srvEntries {
|
|
|
|
if srv.Priority <= bestSrv.Priority && srv.Weight >= bestSrv.Weight {
|
|
|
|
bestSrv = srv
|
|
|
|
addr = fmt.Sprintf("%s:%d", srv.Target, srv.Port)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a := strings.SplitN(addr, ":", 2)
|
|
|
|
if len(a) == 1 {
|
|
|
|
addr += ":5222"
|
|
|
|
}
|
2018-02-11 22:03:58 +01:00
|
|
|
if client.Protocol == "" {
|
|
|
|
client.Protocol = "tcp"
|
2018-02-07 19:32:11 +01:00
|
|
|
}
|
2018-02-11 22:03:58 +01:00
|
|
|
conn, err := net.DialTimeout(client.Protocol, addr, client.Timeout)
|
|
|
|
client.setConnection(conn)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2018-02-07 19:32:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if err = client.connect(password); err != nil {
|
|
|
|
client.Close()
|
2018-02-11 22:03:58 +01:00
|
|
|
return err
|
2018-02-07 19:32:11 +01:00
|
|
|
}
|
2018-02-11 22:03:58 +01:00
|
|
|
return nil
|
2018-02-07 19:32:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Close closes the XMPP connection
|
|
|
|
func (c *Client) Close() error {
|
|
|
|
if c.conn != (*tls.Conn)(nil) {
|
|
|
|
return c.conn.Close()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|