summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2023-06-30 20:03:51 +0200
committerxengineering <me@xengineering.eu>2023-06-30 20:03:51 +0200
commite2c057571ae309cf503851ab8f63c2159f2ef4bc (patch)
treef1b28b26c4501292ee4f6d9836f80f1768e1963b
parent2f1fd4d1ce2c0c2e46fcfa1ffedfd84f0d36484e (diff)
parentd30e2cd84ac54f4ea86f430249f09e272fe9a800 (diff)
downloadlimox-e2c057571ae309cf503851ab8f63c2159f2ef4bc.tar
limox-e2c057571ae309cf503851ab8f63c2159f2ef4bc.tar.zst
limox-e2c057571ae309cf503851ab8f63c2159f2ef4bc.zip
Merge branch 'resource-binding'
This adds some really basic resource binding implementation which will work for now but has to be improved for a first release.
-rw-r--r--ROADMAP.md6
-rw-r--r--xmpp/jid.go65
-rw-r--r--xmpp/router.go8
-rw-r--r--xmpp/stream_pair.go5
4 files changed, 83 insertions, 1 deletions
diff --git a/ROADMAP.md b/ROADMAP.md
index 817df4b..a0934b9 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -7,11 +7,15 @@
- [x] basic XML token logging to console
- [x] infrastructure to route and handle multi-token XML blocks
- [x] SASL authentication
-- [ ] ressource binding
+- [x] ressource binding
- [ ] sending initial presence
- [ ] roster retrieval
- [ ] single user chat text messages
- [ ] SRV record parsing to get TCP port
+- [ ] refactored structure
+- [ ] full error handling
+- [ ] retries
+- [ ] timeouts
## Basic core compliance
diff --git a/xmpp/jid.go b/xmpp/jid.go
index 90c1509..0446d19 100644
--- a/xmpp/jid.go
+++ b/xmpp/jid.go
@@ -1,5 +1,12 @@
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 {
@@ -33,3 +40,61 @@ func username(jid string) string {
return ""
}
+
+func hasBind(e []xml.Token) bool {
+ bind := xml.Name{`urn:ietf:params:xml:ns:xmpp-bind`, `bind`}
+
+ for _, v := range e {
+ switch s := v.(type) {
+ case xml.StartElement:
+ if s.Name == bind {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func (s *session) sendBind() {
+ iqStart := xml.StartElement{
+ xml.Name{"jabber:client", "iq"},
+ []xml.Attr{
+ xml.Attr{xml.Name{"", "id"}, fmt.Sprintf("%016x", rand.Uint64())},
+ xml.Attr{xml.Name{"", "type"}, "set"},
+ },
+ }
+ iqEnd := iqStart.End()
+
+ bindStart := xml.StartElement{
+ xml.Name{"urn:ietf:params:xml:ns:xmpp-bind", "bind"},
+ []xml.Attr{},
+ }
+ bindEnd := bindStart.End()
+
+ resourceStart := xml.StartElement{
+ xml.Name{"", "resource"},
+ []xml.Attr{},
+ }
+ resourceEnd := resourceStart.End()
+
+ name := xml.CharData("limox-" + fmt.Sprintf("%08x", rand.Uint32()))
+
+ tokens := [...]xml.Token{
+ iqStart,
+ bindStart,
+ resourceStart,
+ name,
+ resourceEnd,
+ bindEnd,
+ iqEnd,
+ }
+
+ for _, v := range tokens {
+ err := s.ed.encodeToken(v)
+ if err != nil {
+ log.Println("Could not encode ressource binding!")
+ return
+ }
+ }
+}
diff --git a/xmpp/router.go b/xmpp/router.go
index 9d69033..1d9c3e5 100644
--- a/xmpp/router.go
+++ b/xmpp/router.go
@@ -25,9 +25,17 @@ func getRoutingTable() routingTable {
{xml.Name{`http://etherx.jabber.org/streams`, `features`}, streamFeaturesHandler},
{xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}, saslSuccessHandler},
{xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `failure`}, saslFailureHandler},
+ {xml.Name{`jabber:client`, `iq`}, voidIq},
}
}
+// voidIq just logs that an IQ element was received. In the current state of
+// the software there is no further processing.
+// TODO process IQs for error handling and further information processing.
+func voidIq(s *session, e []xml.Token) {
+ log.Println("Received IQ element")
+}
+
// route determines the correct handler function for the given XML element by a
// given routingTable. In addition it executes the determined handler function.
// If no handler function is found an error message is send via the log module.
diff --git a/xmpp/stream_pair.go b/xmpp/stream_pair.go
index 693972e..4690f57 100644
--- a/xmpp/stream_pair.go
+++ b/xmpp/stream_pair.go
@@ -98,5 +98,10 @@ func streamFeaturesHandler(s *session, e []xml.Token) {
return
}
+ if hasBind(e) {
+ s.sendBind()
+ return
+ }
+
log.Println("Stream has no implemented features!")
}