summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xmpp/iq.go81
-rw-r--r--xmpp/jid.go50
-rw-r--r--xmpp/routing.go6
3 files changed, 84 insertions, 53 deletions
diff --git a/xmpp/iq.go b/xmpp/iq.go
new file mode 100644
index 0000000..1cb7fd5
--- /dev/null
+++ b/xmpp/iq.go
@@ -0,0 +1,81 @@
+package xmpp
+
+import (
+ "encoding/xml"
+ "fmt"
+ "log"
+ "math/rand"
+)
+
+type iqRx struct {
+ XMLName xml.Name `xml:"jabber:client iq"`
+ Type string `xml:"type,attr"`
+ Id string `xml:"id,attr"`
+ Bind struct {
+ Jid string `xml:"jid"`
+ } `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
+ Query []RosterItem `xml:"jabber:iq:roster query>item"`
+}
+
+type RosterItem struct {
+ Jid string `xml:"jid,attr"`
+ Subscription string `xml:"subscription,attr"`
+ Name string `xml:"name,attr"`
+}
+
+func (i iqRx) handle(s *session) {
+ if i.Bind.Jid != "" {
+ s.jid = i.Bind.Jid
+ s.sendPresence()
+ s.sendRosterGet()
+ return
+ }
+
+ if len(i.Query) > 0 {
+ log.Println("Got roster:")
+ for _, v := range i.Query {
+ log.Printf("- %s\n", v.Jid)
+ }
+ }
+}
+
+type bindSet struct {
+ XMLName xml.Name `xml:"jabber:client iq"`
+ Type string `xml:"type,attr,omitempty"`
+ Id string `xml:"id,attr,omitempty"`
+ Bind struct {
+ Resource string `xml:"resource,omitempty"`
+ } `xml:"urn:ietf:params:xml:ns:xmpp-bind bind,omitempty"`
+}
+
+func (s *session) sendBind() {
+ s.resourceReq = fmt.Sprintf("%016x", rand.Uint64())
+
+ req := bindSet{}
+ req.Id = s.resourceReq
+ req.Type = "set"
+ req.Bind.Resource = "limox-" + fmt.Sprintf("%08x", rand.Uint32())
+
+ err := s.tx.Encode(req)
+ if err != nil {
+ log.Println("Could not encode ressource binding!")
+ }
+}
+
+type rosterGet struct {
+ XMLName xml.Name `xml:"jabber:client iq"`
+ Type string `xml:"type,attr,omitempty"`
+ Id string `xml:"id,attr,omitempty"`
+ Query string `xml:"jabber:iq:roster query"`
+}
+
+func (s *session) sendRosterGet() {
+ req := rosterGet{}
+ req.Id = fmt.Sprintf("%016x", rand.Uint64())
+ req.Type = "get"
+
+ err := s.tx.Encode(req)
+ if err != nil {
+ log.Println("Could not encode ressource binding!")
+ }
+}
diff --git a/xmpp/jid.go b/xmpp/jid.go
index 9580ad5..90c1509 100644
--- a/xmpp/jid.go
+++ b/xmpp/jid.go
@@ -1,12 +1,5 @@
package xmpp
-import (
- "encoding/xml"
- "fmt"
- "log"
- "math/rand"
-)
-
// domainpart extracts the domain name from a JID / XMPP address. See
// https://datatracker.ietf.org/doc/html/rfc7622#section-3.2 for details.
func domainpart(jid string) string {
@@ -40,46 +33,3 @@ func username(jid string) string {
return ""
}
-
-type bindRequest struct {
- Bind struct {
- Xmlns string `xml:"xmlns,attr"`
- Resource struct {
- Content string `xml:",chardata"`
- } `xml:"resource"`
- } `xml:"bind"`
-}
-
-func (s *session) sendBind() {
-
- s.resourceReq = fmt.Sprintf("%016x", rand.Uint64())
-
- start := xml.StartElement{
- xml.Name{"jabber:client", "iq"},
- []xml.Attr{
- xml.Attr{xml.Name{"", "id"}, s.resourceReq},
- xml.Attr{xml.Name{"", "type"}, "set"},
- },
- }
-
- inner := bindRequest{}
- inner.Bind.Xmlns = "urn:ietf:params:xml:ns:xmpp-bind"
- inner.Bind.Resource.Content = "limox-" + fmt.Sprintf("%08x", rand.Uint32())
-
- err := s.tx.EncodeElement(inner, start)
- if err != nil {
- log.Println("Could not encode ressource binding!")
- }
-}
-
-type iqResponse struct {
- Jid string `xml:"urn:ietf:params:xml:ns:xmpp-bind bind>jid"`
-}
-
-func handleIqResponse(s *session, i iqResponse) {
- if i.Jid != "" {
- s.jid = i.Jid
- s.sendPresence()
- return
- }
-}
diff --git a/xmpp/routing.go b/xmpp/routing.go
index 2f2347a..4058dfb 100644
--- a/xmpp/routing.go
+++ b/xmpp/routing.go
@@ -12,7 +12,7 @@ func route(s *xml.StartElement, d *xml.Decoder, c chan<- any) {
case xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}:
parse(saslSuccess{}, s, d, c)
case xml.Name{`jabber:client`, `iq`}:
- parse(iqResponse{}, s, d, c)
+ parse(iqRx{}, s, d, c)
case xml.Name{`jabber:client`, `message`}:
parse(message{}, s, d, c)
default:
@@ -35,8 +35,8 @@ func handle(s *session, element any) {
handleStreamFeatures(s, t)
case saslSuccess:
handleSaslSuccess(s)
- case iqResponse:
- handleIqResponse(s, t)
+ case iqRx:
+ t.handle(s)
case message:
handleMessage(s, t)
default: