XMPP sucks

This commit is contained in:
Emery Hemingway 2023-04-24 14:15:05 -05:00
parent 4902e0fb3f
commit a3c7a53776
2 changed files with 40 additions and 23 deletions

View File

@ -1,6 +1,6 @@
# Package # Package
version = "20230412" version = "20230424"
author = "Emery Hemingway" author = "Emery Hemingway"
description = "Jabber Syndicate actor" description = "Jabber Syndicate actor"
license = "Unlicense" license = "Unlicense"

View File

@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense # SPDX-License-Identifier: Unlicense
import std/asyncdispatch, asyncnet, net, strutils import std/[asyncdispatch, asyncnet, net, strutils, xmltree]
import syndicate import syndicate
import getdns import getdns
import ./protocol import ./protocol
@ -14,23 +14,35 @@ proc checkError(r: getdns_return_t) =
type Client = ref object type Client = ref object
context: SslContext context: SslContext
socket: AsyncSocket socket: AsyncSocket
domain, jid: string
proc close(client: Client) = proc close(client: Client) =
try: close(client.socket) try: close(client.socket)
except CatchableError: discard # stupid except CatchableError: discard # stupid
destroyContext(client.context) destroyContext(client.context)
proc connect(client: Client; jid: string) {.async.} = proc runStream(client: Client) {.async.} =
stderr.writeLine "connecting as ", jid block:
var domains = rsplit(jid, '@', 1) var opening = newXmlTree(
stderr.writeLine "domains is ", $domains "stream:stream", [], {
if domains.len != 2: "from": client.jid,
stderr.writeLine "invalid JID ", jid "to": client.domain,
raise newException(ValueError, "invalid JID " & jid) "version": "1.0",
var serviceProtoName = "_xmpps-client._tcp." & domains[1] "xml:lang": "en",
"xmlns": "jabber:client",
"xmlns:stream": "http://etherx.jabber.org/streams",
}.toXmlAttributes)
var txt = $opening
txt.setLen(text.high)
txt[text.high] = '>'
# XMPP streams are not an XML document
await send(client.socket, $opening)
proc connect(client: Client) {.async.} =
var serviceProtoName = "_xmpps-client._tcp." & client.domain
stderr.writeLine "lookup ", serviceProtoName stderr.writeLine "lookup ", serviceProtoName
let dns = getdns.newContext(true) var dns = getdns.newContext(true)
# defer: context_destroy(dns) defer: context_destroy(dns)
dns.setResolutionType(GETDNS_RESOLUTION_STUB) dns.setResolutionType(GETDNS_RESOLUTION_STUB)
var response: Dict var response: Dict
checkError service_sync(dns, serviceProtoName, nil, addr response) checkError service_sync(dns, serviceProtoName, nil, addr response)
@ -40,8 +52,8 @@ proc connect(client: Client; jid: string) {.async.} =
wrapSocket(client.context, client.socket) wrapSocket(client.context, client.socket)
try: try:
let let
host = srvAddr["domain_name"].bindata.toFqdn host = "jabber.spam.works" # srvAddr["domain_name"].bindata.toFqdn
port = srvAddr["port"].int.Port port = Port 5223 # srvAddr["port"].int.Port
stderr.writeLine "connecting to ", host, ":", port stderr.writeLine "connecting to ", host, ":", port
await connect(client.socket, host, port) await connect(client.socket, host, port)
stderr.writeLine "successfully connected to ", host, ":", port stderr.writeLine "successfully connected to ", host, ":", port
@ -51,16 +63,23 @@ proc connect(client: Client; jid: string) {.async.} =
close(client) close(client)
proc bootClient(turn: var Turn; jid, password: string; ds: Ref): Client = proc bootClient(turn: var Turn; jid, password: string; ds: Ref): Client =
result = Client( block:
context: newContext(protTLSv1, CVerifyNone), var domains = rsplit(jid, '@', 1)
socket: newAsyncSocket(), if domains.len != 2:
) stderr.writeLine "invalid JID ", jid
asyncCheck(turn, connect(result, jid)) raise newException(ValueError, "invalid JID " & jid)
result = Client(
context: newContext(protTLSv1, CVerifyNone),
socket: newAsyncSocket(),
domain: domains[1],
jid: jid,
)
waitFor runStream(result)
waitFor connect(result)
waitFor runStream(result)
bootDataspace("main") do (root: Ref; turn: var Turn): bootDataspace("main") do (root: Ref; turn: var Turn):
stderr.writeLine "connectStdio…"
connectStdio(root, turn) connectStdio(root, turn)
stderr.writeLine "stdio connected"
during(turn, root, ?XmppClient) do (jid: string, password: string, ds: Ref): during(turn, root, ?XmppClient) do (jid: string, password: string, ds: Ref):
let client = bootClient(turn, jid, password, ds) let client = bootClient(turn, jid, password, ds)
do: do:
@ -68,5 +87,3 @@ bootDataspace("main") do (root: Ref; turn: var Turn):
close(client) close(client)
runForever() runForever()
{.error: "during clause not active until retraction".}