XMPP sucks
This commit is contained in:
parent
4902e0fb3f
commit
a3c7a53776
|
@ -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"
|
||||||
|
|
|
@ -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".}
|
|
||||||
|
|
Loading…
Reference in New Issue