AH HA!
Honestly, I have no idea if anyone cares about this, but I'm going to document it anyway.
First, I verified that the problem was with my code by writing a very simple proxy. (I still can't see how one uses NERelay!) After all weekend working on it, I got it all working. I cheated and used ObjC for the proxy code, because doing things with sockets was easier.
Second: having my simple TPP app successfully using a proxy, I took the changes I'd made to my code for the provider over to our real app, and it immediately continued to not work.
After days of working on that, the bulk of my problems were due to my Swift clumsiness.
In one case:
let nwritten = data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in
var t = ptr
let count = data.count
let kr = Darwin.write(self.socket, &t, count)
return kr
}
That did a great job of writing the UnsafeRawBufferPointer to the socket, when what I wanted was, obviously, the data that it pointed to.
Similarly, in another place, I had
var buffer = message.data(using: .ascii)!
let nwritten = Darwin.write(self.socket, &buffer, buffer.count)
and yeah that wasn't right. I changed them both to be variants of
let nwritten = buffer.withUnsafeBytes { ptr in
return Darwin.write(self.socket, ptr, buffer.count)
}
and then AMAZINGLY it all started working!