Created
June 29, 2020 04:14
-
-
Save anacrolix/06ba77f570c7f3f315b0ad1afcc1ecdc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use "net" | |
use "logger" | |
use "time" | |
actor Main | |
new create(env: Env) => | |
let auth = | |
try | |
env.root as AmbientAuth | |
else | |
env.exitcode(1) | |
env.err.print("bad root auth") | |
return | |
end | |
RunServer(auth, env) | |
actor RunServer | |
let _auth: AmbientAuth | |
let _env: Env | |
var _server: (DhtServer|None) = None | |
new create(auth: AmbientAuth, env: Env) => | |
_auth = auth | |
_env = env | |
UDPSocket(_auth, recover MyNotify(env, this, auth) end where service = "42069") | |
be socket_ready(sock: UDPSocket) => | |
dispose_server() | |
_server = DhtServer( | |
sock, | |
DNSAuth(_auth), | |
StringLogger(Fine, _env.out)) | |
.>bootstrap() | |
fun dispose_server() => | |
try | |
(_server as DhtServer).dispose() | |
end | |
be socket_closed() => | |
dispose_server() | |
primitive StringifyNetAddress | |
fun apply(na: NetAddress, reversedns: (DNSLookupAuth | None) = None): String => | |
(let host, let service) = | |
try | |
na.name(where reversedns=reversedns)? | |
else | |
return "unknown" | |
end | |
host + ":" + service + "(" + _if(na.ip4(), "4") + _if(na.ip6(), "6") + ")" | |
fun _if(b: Bool, c: String): String => | |
if b then c else "" end | |
class MyNotify | |
let _env: Env | |
let _notify: RunServer | |
let _auth: (DNSLookupAuth|None) | |
new create(env: Env, notify: RunServer, auth: (DNSLookupAuth|None)) => | |
_env = env | |
_notify = notify | |
_auth = auth | |
fun listening(sock: UDPSocket ref) => | |
_env.out.print("listening at "+StringifyNetAddress(sock.local_address())) | |
_notify.socket_ready(sock) | |
fun received(_: UDPSocket, data: Array[U8 val] iso, from: NetAddress val) => | |
_env.out.print("got reply from " + StringifyNetAddress(from) + ": " + String.from_array(consume data)) | |
fun not_listening(_: UDPSocket) => | |
_env.err.print("not listening") | |
fun closed(_: UDPSocket) => | |
_env.err.print("socket closed") | |
_notify.socket_closed() | |
primitive GlobalBootstrapAddrs | |
fun apply(): Array[(String, String)] val => | |
[ | |
("router.utorrent.com", "6881") | |
("router.bittorrent.com", "6881") | |
("dht.transmissionbt.com", "6881") | |
("dht.aelitis.com", "6881") // Vuze | |
("router.silotis.us", "6881") // IPv6 | |
("dht.libtorrent.org", "25401") | |
] | |
actor DhtServer | |
let _socket: UDPSocket | |
let _auth: DNSLookupAuth | |
let _logger: Logger[String] | |
let _timers: Timers = Timers | |
var outstanding: USize = 0 | |
new create(socket: UDPSocket, auth: DNSLookupAuth, logger: Logger[String]) => | |
_socket = socket | |
_auth = auth | |
_logger = logger | |
be bootstrap(addrs: Array[(String,String)] val = GlobalBootstrapAddrs()) => | |
for (host, service) in addrs.values() do | |
for na in DNS(_auth, host, service).values() do | |
ping(na) | |
end | |
end | |
be dispose() => | |
_timers.dispose() | |
_socket.dispose() | |
be completed_transaction() => | |
outstanding = outstanding - 1 | |
_logger(Fine) and _logger.log(outstanding.string()) | |
if outstanding == 0 then | |
dispose() | |
end | |
be ping(na: NetAddress) => | |
_logger(Fine) and _logger.log("pinging: " + StringifyNetAddress(na)) | |
_socket.write("d1:ad2:id20:55ca6286e3e4f4fba5d0e1:q4:ping1:t3:xxx1:y1:qe", na) | |
outstanding = outstanding + 1 | |
let server = recover this end | |
_timers(Timer( | |
object iso is TimerNotify | |
fun apply(_: Timer, _: U64): Bool => | |
server.completed_transaction() | |
false | |
end, | |
Nanos.from_seconds(2))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment