all repos — honk @ 7fb85a75f618a25acc66c89cf7d131cfaf75509a

my fork of honk

a ping extension to hlp debug network problems
Ted Unangst tedu@tedunangst.com
Fri, 12 Apr 2019 12:32:07 -0400
commit

7fb85a75f618a25acc66c89cf7d131cfaf75509a

parent

5621dd48b557446c1e4805e1524b341f675b7757

3 files changed, 150 insertions(+), 1 deletions(-)

jump to
M honk.gohonk.go

@@ -273,6 +273,48 @@ }

return false } +func ping(user *WhatAbout, who string) { + inbox, _, err := getboxes(who) + if err != nil { + log.Printf("no inbox for ping: %s", err) + return + } + j := NewJunk() + j["@context"] = itiswhatitis + j["type"] = "Ping" + j["id"] = user.URL + "/ping/" + xfiltrate() + j["actor"] = user.URL + j["to"] = who + keyname, key := ziggy(user) + err = PostJunk(keyname, key, inbox, j) + if err != nil { + log.Printf("can't send ping: %s", err) + return + } + log.Printf("sent ping to %s: %s", who, j["id"]) +} + +func pong(user *WhatAbout, who string, obj string) { + inbox, _, err := getboxes(who) + if err != nil { + log.Printf("no inbox for pong %s : %s", who, err) + return + } + j := NewJunk() + j["@context"] = itiswhatitis + j["type"] = "Pong" + j["id"] = user.URL + "/pong/" + xfiltrate() + j["actor"] = user.URL + j["to"] = who + j["object"] = obj + keyname, key := ziggy(user) + err = PostJunk(keyname, key, inbox, j) + if err != nil { + log.Printf("can't send pong: %s", err) + return + } +} + func inbox(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] user, err := butwhatabout(name)

@@ -315,6 +357,13 @@ return

} what, _ := jsongetstring(j, "type") switch what { + case "Ping": + obj, _ := jsongetstring(j, "id") + log.Printf("ping from %s: %s", who, obj) + pong(user, who, obj) + case "Pong": + obj, _ := jsongetstring(j, "object") + log.Printf("pong from %s: %s", who, obj) case "Follow": log.Printf("updating honker follow: %s", who) rubadubdub(user, j)

@@ -1058,7 +1107,6 @@ func serve() {

db := opendatabase() LoginInit(db) - getconfig("servername", &serverName) listener, err := openListener() if err != nil { log.Fatal(err)

@@ -1224,8 +1272,22 @@ }

if cmd != "init" { db := opendatabase() prepareStatements(db) + getconfig("servername", &serverName) } switch cmd { + case "ping": + if len(os.Args) < 4 { + fmt.Printf("usage: honk ping from to\n") + return + } + name := os.Args[2] + targ := os.Args[3] + user, err := butwhatabout(name) + if err != nil { + log.Printf("unknown user") + return + } + ping(user, targ) case "peep": peeppeep() case "init":
A ping.txt

@@ -0,0 +1,85 @@

+ +A Ping extension for ActivityPub + +-- rationale + +Diagnosing communication failures between federated servers often requires +sending test messages. There is no dedicated activity type for this purpose, +however, and thus many operators use normal notes. This creates unnecessary +noise. It would be better to have a side effect free message that can be +triggered and sent on demand. + +The proposed Ping and corresponding Pong activities are similar to the ICMP +echo request and echo reply messages. (c.f. the familiar ping tool.) + +Other online social contexts often use the term ping to refer to a variety +of activities. The activity here is unrelated to any user visible activity or +action. + +-- message format + +The ping message has a type of Ping. Here, user pinger on server +h1.example.com is sending a Ping to testrcpt on h2.example.com. + +{ + "@context": "https://www.w3.org/ns/activitystreams", + "type": "Ping", + "id": "https://h1.example.com/u/pinger/ping/r4nd0m1d", + "actor": "https://h1.example.com/u/pinger", + "to": "https://h2.example.com/u/testrcpt" +} + +The Pong message is similar, but includes an object field quoting the Ping id +field. + +{ + "@context": "https://www.w3.org/ns/activitystreams", + "type": "Pong", + "id": "https://h2.example.com/u/testrcpt/pong/0pp0s1t3", + "actor": "https://h2.example.com/u/testrcpt", + "to": "https://h1.example.com/u/pinger", + "object": "https://h1.example.com/u/pinger/ping/r4nd0m1d" +} + +Ping and Pong id fields look like URLs, but need not be fetchable. They are +only intended as transient messages. + +-- semantics + +The Ping message should be sent from one actor to another, delivered to their +inbox. Upon receipt of a Ping message, a server should reply with a Pong +message. The Pong reply should quote the id of the Ping (just the id, not the +whole message) in the object field. + +Random ids may used. They should be probabilistically unique. + +The usual access and verification checks performed for other messages should +be performed for Ping and Pong as well. (If HTTP signatures are in use, +messages should be signed by senders and verified by receivers.) + +Ping and Pong messages should be queued using the normal facilities. (Don't +fast track.) Messages should not be retried. After one failure, drop the +message. + +As these messages are intended as administrator aids, they should not be +displayed to end users. They should not cause any lasting change in the state +of either the sending or receiving server. + +Rate limiting and abuse controls apply as usual. Servers may choose to impose +length restrictions on maximum id length. A minimum of 256 bytes should be +supported. + +Servers which do not understand the Ping activity will hopefully ignore it. + +-- usage + +It is unspecified how one initiaties a ping, but it is expected to be a manual +operation performed by a system adminstrator. This will generate traffic, +which may then be logged. The admin reads the logs and solves the problem. +Specific problem solving instructions are not provided here. + +-- future + +It may be helpful to have a variant of Ping that does perform retries to test +recovery after disconnect. +
M spec.txtspec.txt

@@ -4,6 +4,8 @@ -- references

See security.txt for some notes on security. +See ping.txt for a proposed Ping extension to ActivityPub. + -- schema Some notes on the database schema. Mostly for development, but maybe useful