#!/usr/bin/env racket #lang racket ; vim:syntax=racket (require json "iputil.rkt" "unix-socket.rkt" "msg.rkt") ;; info : Peer ;; sock-in : Input-Port ;; sock-out : Output-Port (struct peer-conn [info sock-in sock-out] #:transparent) ;; Str [Listof Peer-Conn] -> Void ;; -- ;; Runs router logic, given a list of peer connections. (define (run-router/conns ans peer-conns) (define mail (make-channel)) (define peer-threads (for/list ([pc (in-list peer-conns)]) (match-define (peer-conn peer sock-in sock-out) pc) (thread (λ () (define buf (make-bytes 65536)) (let loop () (define len (read-bytes-avail! buf sock-in)) (printf "got ~a bytes from ~a...\n" len peer) (define msg (bytes->msg (subbytes buf 0 len))) (channel-put mail (list peer msg)) (loop)))))) (define (loop) (match-define (list peer data) (channel-get mail)) (printf "from ~a:\n~s\n" peer data) (loop)) (printf "waiting for messages...\n") (loop)) ;; Str [Listof Peer] -> ;; Router main (define (run-router asn peers) (displayln asn) (map displayln peers) (displayln "------------") (with-handlers ([exn:break? (λ (e) (printf "time to die.\n"))]) (run-router/conns asn (for/list ([peer (in-list peers)]) (define-values [sock-in sock-out] (unix-socket-connect (ip->string (peer-ip peer)) 'SOCK-SEQPACKET)) (peer-conn peer sock-in sock-out))))) (module+ main (command-line #:program "router" #:args (asn . peers) (with-output-to-file "log.txt" #:exists 'replace (λ () ;; Run the router (run-router asn (map string->peer peers)))))) (module+ test (define-values [in1 out1] (make-pipe)) (define-values [in2 out2] (make-pipe)) (define p1 (peer-conn (string->peer "1.2.3.4-cust") in1 out1)) (define p2 (peer-conn (string->peer "1.2.3.5-peer") in2 out2)) ; (define abort-router (run-router/conns "123" (list p1 p2)) (void (write-string "{\"a\": 1, \"b\": [1,2,3]}" out1)))