Random cleanup.
[small-scheme-stack.git] / port.scm
blobd305e8ba73f88f9c5194e7d03d954fe9ab5b6fda
1 ;;;; Lysiane Bouchard - Vincent St-Amour
2 ;;;; port.scm
4 ;;;  - port structure description and operations
5 ;;;  - port configuration description and operations
6 ;;;  - port binding functions
7 ;;;  - port number conversion functions
10 ;; a port structure is a pair (conf . conns)
11 ;; the car is a port configuration stucture, described below
12 ;; the cdr is a list containing all the active connections on this port
13 (define (add-conn-to-curr-port conn)
14   (set-cdr! curr-port (cons conn (cdr curr-port)))) ;; TODO inline ? would leak the specification, but still
15 (define (get-curr-conns) (cdr curr-port)) 
17 ;; conf structures are represented as vectors :
18 ;; -0: port number (integer)
19 ;; -1: maximum number of connections (integer)
20 ;;     applies only to TCP
21 ;; -2: filter function (function)
22 ;;     this function is a predicate that returns true if the application
23 ;;     accepts the connection. it takes the destination's ip, the source's ip
24 ;;     (as length 4 u8vectors) and the source's port (as an integer) as
25 ;;     arguments
26 ;; -3: reception function (function)
27 ;;     TCP :
28 ;;     this function takes the connection structure as argument and is called
29 ;;     when the connection is created by the stack. The application can then
30 ;;     access the input and output buffers of the connection at any time.
31 ;;     UDP :
32 ;;     this function takes the source IP and the source port number of the
33 ;;     datagram along with a vector containing the data of the datagram.
34 ;;     the application handles the datagram in this function, and can send a
35 ;;     reply in it
36 (define conf-portnum   0)
37 (define conf-max-conns 1)
38 (define conf-filter    2)
39 (define conf-reception 3)
40 (define (conf-ref port i) (vector-ref (car port) i))
43 ;;; server management
45 (define (search-port portnum ports)
46   (memp (lambda (p) (= portnum (conf-ref p conf-portnum))) ports))
48 ;; homologuous to BSD sockets', to be called from the application
49 ;; takes the port number, the maximum simultaneous number of connections and
50 ;; application filter and linker functions
51 (define (tcp-bind portnum max-conns filter linker)
52   (if (search-port portnum tcp-ports)
53       #f
54       (begin
55         (set! tcp-ports (cons (cons (vector portnum max-conns filter linker)
56                                     '())
57                               tcp-ports))
58         #t)))
59 ;; TODO can we detach a port form a ports ? if the application terminates, for example
60 ;; TODO maybe, if we try to bind a port that is already bound, get rid of the old server structure ?
62 ;; similar to TCP's, but doesn't take the maximum number of connections
63 (define (udp-bind portnum filter linker)
64   (if (search-port portnum udp-ports)
65       #f
66       (begin
67         (set! udp-ports (cons (cons (vector portnum 0 filter linker) '())
68                               udp-ports))
69         #t)))
71 ;; does the ip datagram pass the filter of the current port ?
72 (define (pass-app-filter? src-portnum-idx port)
73   (let ((dst-ip (u8vector-ref-field pkt ip-destination-ip 4)) ; length 4 u8vector
74         (src-ip (u8vector-ref-field pkt ip-source-ip 4)) ; length 4 u8vector
75         (src-portnum-ref (pkt-ref-2 src-portnum-idx))) ; integer
76     ((conf-ref port conf-filter) dst-ip src-ip src-portnum-ref)))
79 ;;; simple conversion functions
80 (define (portnum->u8vector n)
81   (u8vector (quotient n 256) (modulo n 256)))
82 (define (u8vector->portnum v)
83   (+ (* 256 (u8vector-ref v 0)) (u8vector-ref v 1)))