xmpp/xmpp.go
changeset 148 b1b4900eee5b
parent 147 d7679d991b17
child 153 bbd4166df95d
equal deleted inserted replaced
147:d7679d991b17 148:b1b4900eee5b
    13 	"errors"
    13 	"errors"
    14 	"fmt"
    14 	"fmt"
    15 	"io"
    15 	"io"
    16 	"net"
    16 	"net"
    17 	"reflect"
    17 	"reflect"
    18 	"sync"
       
    19 )
    18 )
    20 
    19 
    21 const (
    20 const (
    22 	// Version of RFC 3920 that we implement.
    21 	// Version of RFC 3920 that we implement.
    23 	XMPPVersion = "1.0"
    22 	XMPPVersion = "1.0"
    37 	clientSrv = "xmpp-client"
    36 	clientSrv = "xmpp-client"
    38 )
    37 )
    39 
    38 
    40 // Flow control for preventing sending stanzas until negotiation has
    39 // Flow control for preventing sending stanzas until negotiation has
    41 // completed.
    40 // completed.
    42 type sendCmd bool
    41 type sendCmd int
       
    42 
       
    43 const (
       
    44 	sendAllowConst = iota
       
    45 	sendDenyConst
       
    46 	sendAbortConst
       
    47 )
    43 
    48 
    44 var (
    49 var (
    45 	sendAllow sendCmd = true
    50 	sendAllow sendCmd = sendAllowConst
    46 	sendDeny  sendCmd = false
    51 	sendDeny  sendCmd = sendDenyConst
       
    52 	sendAbort sendCmd = sendAbortConst
    47 )
    53 )
    48 
    54 
    49 // A filter can modify the XMPP traffic to or from the remote
    55 // A filter can modify the XMPP traffic to or from the remote
    50 // server. It's part of an Extension. The filter function will be
    56 // server. It's part of an Extension. The filter function will be
    51 // called in a new goroutine, so it doesn't need to return. The filter
    57 // called in a new goroutine, so it doesn't need to return. The filter
    70 type Client struct {
    76 type Client struct {
    71 	// This client's JID. This will be updated asynchronously by
    77 	// This client's JID. This will be updated asynchronously by
    72 	// the time StartSession() returns.
    78 	// the time StartSession() returns.
    73 	Jid          JID
    79 	Jid          JID
    74 	password     string
    80 	password     string
    75 	socket       net.Conn
       
    76 	socketSync   sync.WaitGroup
       
    77 	saslExpected string
    81 	saslExpected string
    78 	authDone     bool
    82 	authDone     bool
    79 	handlers     chan *callback
    83 	handlers     chan *callback
    80 	inputControl chan sendCmd
    84 	inputControl chan sendCmd
    81 	// Incoming XMPP stanzas from the remote will be published on
    85 	// Incoming XMPP stanzas from the remote will be published on
    96 	// StartSession() returns.
   100 	// StartSession() returns.
    97 	Features                     *Features
   101 	Features                     *Features
    98 	sendFilterAdd, recvFilterAdd chan Filter
   102 	sendFilterAdd, recvFilterAdd chan Filter
    99 	// Allows the user to override the TLS configuration.
   103 	// Allows the user to override the TLS configuration.
   100 	tlsConfig tls.Config
   104 	tlsConfig tls.Config
       
   105 	layer1    *layer1
   101 }
   106 }
   102 
   107 
   103 // Connect to the appropriate server and authenticate as the given JID
   108 // Connect to the appropriate server and authenticate as the given JID
   104 // with the given password. This function will return as soon as a TCP
   109 // with the given password. This function will return as soon as a TCP
   105 // connection has been established, but before XMPP stream negotiation
   110 // connection has been established, but before XMPP stream negotiation
   143 
   148 
   144 	cl := new(Client)
   149 	cl := new(Client)
   145 	cl.Roster = *roster
   150 	cl.Roster = *roster
   146 	cl.password = password
   151 	cl.password = password
   147 	cl.Jid = *jid
   152 	cl.Jid = *jid
   148 	cl.socket = tcp
       
   149 	cl.handlers = make(chan *callback, 100)
   153 	cl.handlers = make(chan *callback, 100)
   150 	cl.inputControl = make(chan sendCmd)
   154 	cl.inputControl = make(chan sendCmd)
   151 	cl.tlsConfig = tlsconf
   155 	cl.tlsConfig = tlsconf
   152 	cl.sendFilterAdd = make(chan Filter)
   156 	cl.sendFilterAdd = make(chan Filter)
   153 	cl.recvFilterAdd = make(chan Filter)
   157 	cl.recvFilterAdd = make(chan Filter)
   164 	}
   168 	}
   165 
   169 
   166 	// Start the transport handler, initially unencrypted.
   170 	// Start the transport handler, initially unencrypted.
   167 	recvReader, recvWriter := io.Pipe()
   171 	recvReader, recvWriter := io.Pipe()
   168 	sendReader, sendWriter := io.Pipe()
   172 	sendReader, sendWriter := io.Pipe()
   169 	go cl.recvTransport(recvWriter)
   173 	cl.layer1 = startLayer1(tcp, recvWriter, sendReader)
   170 	go cl.sendTransport(sendReader)
       
   171 
   174 
   172 	// Start the reader and writer that convert to and from XML.
   175 	// Start the reader and writer that convert to and from XML.
   173 	recvXmlCh := make(chan interface{})
   176 	recvXmlCh := make(chan interface{})
   174 	go recvXml(recvReader, recvXmlCh, extStanza)
   177 	go recvXml(recvReader, recvXmlCh, extStanza)
   175 	sendXmlCh := make(chan interface{})
   178 	sendXmlCh := make(chan interface{})