1package xmpp 2 3import ( 4 "encoding/xml" 5 "io" 6 "log" 7 "net" 8 "time" 9 10 "github.com/coyim/coyim/xmpp/data" 11) 12 13var ( 14 keepaliveInterval = 10 * time.Second 15 keepaliveTimeout = 30 * time.Second 16) 17 18const logKeepAlives = false 19 20// Manage whitespace keepalives as specified in RFC 6120, section 4.6.1 21func (c *conn) watchKeepAlive(conn net.Conn) { 22 tick := time.NewTicker(keepaliveInterval) 23 defer tick.Stop() 24 defer log.Println("xmpp: no more watching keepalives") 25 26 for _ = range tick.C { 27 if c.closed { 28 return 29 } 30 31 if c.sendKeepalive() { 32 if logKeepAlives { 33 log.Println("xmpp: keepalive sent") 34 } 35 continue 36 } 37 38 log.Println("xmpp: keepalive failed") 39 40 go c.sendStreamError(data.StreamError{ 41 DefinedCondition: data.ConnectionTimeout, 42 }) 43 44 return 45 } 46} 47 48func (c *conn) sendKeepalive() bool { 49 _, err := c.keepaliveOut.Write([]byte{0x20}) 50 return c.closed || err == nil || err == io.EOF 51} 52 53func (c *conn) sendStreamError(streamError data.StreamError) error { 54 enc, err := xml.Marshal(streamError) 55 if err != nil { 56 return err 57 } 58 59 //This is expected to error since the connection may be unreliable at this moment 60 c.out.Write(enc) 61 62 return c.Close() 63} 64