Introduction
Introduction Statistics Contact Development Disclaimer Help
tOpenTransportUDP.lisp - clic - Clic is an command line interactive client for …
git clone git://bitreich.org/clic/ git://hg6vgqziawt5s4dj.onion/clic/
Log
Files
Refs
Tags
LICENSE
---
tOpenTransportUDP.lisp (6398B)
---
1 ;;;-*-Mode: LISP; Package: CCL -*-
2 ;;
3 ;;; OpenTransportUDP.lisp
4 ;;; Copyright 2012 Chun Tian (binghe) <[email protected]>
5
6 ;;; UDP extension to OpenTransport.lisp (with some TCP patches)
7
8 (in-package "CCL")
9
10 (eval-when (:compile-toplevel :load-toplevel :execute)
11 (require :opentransport))
12
13 ;; MCL Issue 28: Passive TCP streams should be able to listen to the loo…
14 ;; see http://code.google.com/p/mcl/issues/detail?id=28 for details
15
16 (defparameter *passive-interface-address* NIL
17 "Address to use for passive connections - optionally bind to loopback …
18
19 (advise local-interface-ip-address
20 (or *passive-interface-address* (:do-it))
21 :when :around :name 'override-local-interface-ip-address)
22
23 ;; MCL Issue 29: Passive TCP connections on OS assigned ports
24 ;; see http://code.google.com/p/mcl/issues/detail?id=29 for details
25 (advise ot-conn-tcp-passive-connect
26 (destructuring-bind (conn port &optional (allow-reuse t)) arglist
27 (declare (ignore allow-reuse))
28 (if (eql port #$kOTAnyInetAddress)
29 ;; Avoids registering a proxy for port 0 but instead registers o…
30 (multiple-value-bind (proxy result)
31 (let* ((*opentransport-class-proxies* NIL) ; makes ot-find-p…
32 (result (:do-it)) ;; pushes onto *opentransport-class…
33 (proxy (prog1
34 (pop *opentransport-class-proxies*)
35 (assert (not *opentransport-class-proxies*))…
36 (context (cdr proxy))
37 (tmpconn (make-ot-conn :context context
38 :endpoint (pref context :ot-co…
39 (localaddress (ot-conn-tcp-get-addresses tmpconn)))
40 (declare (dynamic-extent tmpconn))
41 ;; replace original set in body of function
42 (setf (ot-conn-local-address conn) localaddress)
43 (values
44 (cons localaddress context)
45 result))
46 ;; need to be outside local binding of *opentransport-class-pr…
47 (without-interrupts
48 (push proxy *opentransport-class-proxies*))
49 result)
50 (:do-it)))
51 :when :around :name 'ot-conn-tcp-passive-connect-any-address)
52
53 (defun open-udp-socket (&key local-address local-port)
54 (init-opentransport)
55 (let (endpoint ; TODO: opentransport-alloc-endpoint-from-freelist
56 (err #$kOTNoError)
57 (configptr (ot-cloned-configuration traps::$kUDPName)))
58 (rlet ((errP :osstatus))
59 (setq endpoint #+carbon-compat (#_OTOpenEndpointInContext configpt…
60 #-carbon-compat (#_OTOpenEndpoint configptr 0 (%nul…
61 err (pref errP :osstatus))
62 (if (eql err #$kOTNoError)
63 (let* ((context (ot-make-endpoint-context endpoint nil nil)) ;…
64 (conn (make-ot-conn :context context :endpoint endpoint…
65 (macrolet ((check-ot-error-return (error-context)
66 `(unless (eql (setq err (pref errP :osstatus)) …
67 (values (ot-error err ,error-context)))))
68 (setf (ot-conn-bindreq conn)
69 #-carbon-compat (#_OTAlloc endpoint #$T_BIND #$T_ADD…
70 #+carbon-compat (#_OTAllocInContext endpoint #$T_BIN…
71 )
72 (check-ot-error-return :alloc)
73 (setf (ot-conn-bindret conn)
74 #-carbon-compat (#_OTAlloc endpoint #$T_BIND #$T_ADD…
75 #+carbon-compat (#_OTAllocInContext endpoint #$T_BIN…
76 )
77 (check-ot-error-return :alloc)
78 (setf (ot-conn-options conn)
79 #-carbon-compat (#_OTAlloc endpoint #$T_OPTMGMT #$T_…
80 #+carbon-compat (#_OTAllocInContext endpoint #$T_OPT…
81 )
82 (check-ot-error-return :alloc))
83 ;; BIND to local address (for UDP server)
84 (when local-port ; local-address
85 (let* ((host (or local-address (local-interface-ip-address…
86 (port (tcp-service-port-number local-port))
87 (localaddress `(:tcp ,host ,port))
88 (bindreq (ot-conn-bindreq conn))
89 (bindret (ot-conn-bindret conn)))
90 (let* ((netbuf (pref bindreq :tbind.addr)))
91 (declare (dynamic-extent netbuf))
92 (setf (pref netbuf :tnetbuf.len) (record-length :ineta…
93 (pref bindreq :tbind.qlen) 5) ; arbitrary …
94 (#_OTInitInetAddress (pref netbuf :tnetbuf.buf) port h…
95 (setf (pref context :ot-context.completed) nil)
96 (unless (= (setq err (#_OTBind endpoint bindreq bindre…
97 (ot-error err :bind)))
98 (setf (ot-conn-local-address conn) localaddress)))
99 conn)
100 (ot-error err :create)))))
101
102 (defun make-TUnitData (endpoint)
103 "create the send/recv buffer for UDP sockets"
104 (let ((err #$kOTNoError))
105 (rlet ((errP :osstatus))
106 (macrolet ((check-ot-error-return (error-context)
107 `(unless (eql (setq err (pref errP :osstatus)) #$kOTN…
108 (values (ot-error err ,error-context)))))
109 (let ((udata #-carbon-compat (#_OTAlloc endpoint #$T_UNITDATA #$…
110 #+carbon-compat (#_OTAllocInContext endpoint #$T_UN…
111 (check-ot-error-return :alloc)
112 udata)))))
113
114 (defun send-message (conn data buffer size host port &optional (offset 0…
115 ;; prepare dest address
116 (let ((addr (pref data :tunitdata.addr)))
117 (declare (dynamic-extent addr))
118 (setf (pref addr :tnetbuf.len) (record-length :inetaddress))
119 (#_OTInitInetAddress (pref addr :tnetbuf.buf) port host))
120 ;; prepare data buffer
121 (let* ((udata (pref data :tunitdata.udata))
122 (outptr (pref udata :tnetbuf.buf)))
123 (declare (dynamic-extent udata))
124 (%copy-ivector-to-ptr buffer offset outptr 0 size)
125 (setf (pref udata :tnetbuf.len) size))
126 ;; send the packet
127 (let* ((endpoint (ot-conn-endpoint conn))
128 (result (#_OTSndUData endpoint data)))
129 (the fixnum result)))
130
131 (defun receive-message (conn data buffer length)
132 (let* ((endpoint (ot-conn-endpoint conn))
133 (err (#_OTRcvUData endpoint data *null-ptr*)))
134 (if (eql err #$kOTNoError)
135 (let* (;(addr (pref data :tunitdata.addr))
136 (udata (pref data :tunitdata.udata))
137 (inptr (pref udata :tnetbuf.buf))
138 (read-bytes (pref udata :tnetbuf.len))
139 (buffer (or buffer (make-array read-bytes :element-type '…
140 (length (or length (length buffer)))
141 (actual-size (min read-bytes length)))
142 (%copy-ptr-to-ivector inptr 0 buffer 0 actual-size)
143 (values buffer
144 actual-size
145 0 0)) ; TODO: retrieve address and port
146 (ot-error err :receive)))) ; TODO: use OTRcvUDErr instead
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.