|
0
|
1 |
.include "DS.S"
|
|
|
2 |
.data
|
|
|
3 |
.text
|
|
|
4 |
#-----------------------------------------------
|
|
|
5 |
# N O D E O P E R A T I O N S
|
|
|
6 |
#-----------------------------------------------
|
|
|
7 |
ARGS
|
|
|
8 |
DS CnstlnP # -->Constellation inst
|
|
|
9 |
DS port # node's port#
|
|
|
10 |
# returns
|
|
|
11 |
# nothing
|
|
|
12 |
# local vars
|
|
|
13 |
PROLOC
|
|
|
14 |
DL this, NodeL # this Node instance
|
|
|
15 |
DL thisP # -->this Node
|
|
|
16 |
DL deP # -->Debug inst for LOG macro
|
|
|
17 |
DL rc
|
|
|
18 |
DL tosignal # switch
|
|
|
19 |
DL sigact, SigActionL
|
|
|
20 |
DL sigmask, 128
|
|
|
21 |
DL sigret
|
|
|
22 |
EPILOC
|
|
|
23 |
#-----------------------------------------------
|
|
|
24 |
.global Node
|
|
|
25 |
Node:
|
|
|
26 |
PROLOG
|
|
|
27 |
lea this(bp), b # -->this Node
|
|
|
28 |
mov b, thisP(bp) # save -->this Node
|
|
|
29 |
lea N.debug(b), a
|
|
|
30 |
mov a, deP(bp) # save -->Debug locally for LOG macro
|
|
|
31 |
# save parm values
|
|
|
32 |
mov CnstlnP(bp), c # -->Constellation
|
|
|
33 |
mov c, N.cnstlnP(b) # save -->Constellation
|
|
|
34 |
mov port(bp), a
|
|
|
35 |
mov a, N.locPort(b) # save port#
|
|
|
36 |
# set Debug id
|
|
|
37 |
push a
|
|
|
38 |
cmpl $Cn.ring, Cn.topo(c)
|
|
|
39 |
je 0f
|
|
|
40 |
push $8f
|
|
|
41 |
jmp 1f
|
|
|
42 |
0: push $7f
|
|
|
43 |
1: cmp $0,Cn.ssl(c)
|
|
|
44 |
je 2f
|
|
|
45 |
push $6f
|
|
|
46 |
jmp 9f
|
|
|
47 |
2: push $5f
|
|
|
48 |
jmp 9f
|
|
|
49 |
5: .asciz "non"
|
|
|
50 |
6: .asciz ""
|
|
|
51 |
7: .asciz "RING"
|
|
|
52 |
8: .asciz "MASH"
|
|
|
53 |
9: DEBID "%sSSL %s node %d", 3 # N->ssl ? "" : "non", N.topo==mash ? "MASH" : "RING", locPort
|
|
|
54 |
call N.init # initialize node
|
|
|
55 |
call N.bind # bind node to local port
|
|
|
56 |
push N.kicker(b) # kicker indicator
|
|
|
57 |
LOG 5, "kicker=%d"
|
|
|
58 |
cmpl $0, N.kicker(b) # kicker ?
|
|
|
59 |
je 0f # no
|
|
|
60 |
call N.kickOff # start transfer
|
|
|
61 |
0:
|
|
|
62 |
call N.mainLoop # iterate on socket I/O select
|
|
|
63 |
LOG 5, "closing ssc"
|
|
|
64 |
push N.ssc(b)
|
|
|
65 |
SYS close
|
|
|
66 |
movl $0, rc(bp) # rc = OK
|
|
|
67 |
# wait on thread closing client side
|
|
|
68 |
cmpl $0, N.closing(b) # closing client side ?
|
|
|
69 |
je N.chkData # no
|
|
|
70 |
push $0
|
|
|
71 |
push N.ptid(b) # thread id
|
|
|
72 |
call pthread_join
|
|
|
73 |
test a, a
|
|
|
74 |
jz 1f
|
|
|
75 |
push a # unique error handlig for pthread_join
|
|
|
76 |
call strerror
|
|
|
77 |
push a
|
|
|
78 |
LOG 0, "pthread_join: %s"
|
|
|
79 |
push deP(bp)
|
|
|
80 |
call C.abend
|
|
|
81 |
1:
|
|
|
82 |
mov thisP(bp), b # -->this Node
|
|
|
83 |
push N.pid(b)
|
|
|
84 |
LOG 5, "task %u: closing thread returned"
|
|
|
85 |
# synchronize with all nodes in all constellations and then check received data
|
|
|
86 |
N.chkData:
|
|
|
87 |
call N.sync # wait for others
|
|
|
88 |
cmpl $0, N.kicker(b) # kicker ?
|
|
|
89 |
je 0f # no
|
|
|
90 |
|
|
|
91 |
push N.dataP(b) # -->Data
|
|
|
92 |
call Da.chk
|
|
|
93 |
test a, a # data check OK ?
|
|
|
94 |
jnz 0f # yes
|
|
|
95 |
movl $1, rc(bp) # rc = BAD
|
|
|
96 |
LOG 0, "data on INPUT TO and OUTPUT FROM constellation DIFFER"
|
|
|
97 |
0:
|
|
|
98 |
push N.pid(b)
|
|
|
99 |
push rc(bp)
|
|
|
100 |
LOG 2, "end of operations, rc=%d, process=%u"
|
|
|
101 |
call exit
|
|
|
102 |
#-----------------------------------------------
|
|
|
103 |
# C O N S T R U C T O R
|
|
|
104 |
#-----------------------------------------------
|
|
|
105 |
PROLOC
|
|
|
106 |
DL thisP # -->this Node
|
|
|
107 |
DL deP # -->Debug
|
|
|
108 |
# DL CnstlnP # -->Constellation
|
|
|
109 |
DL len # various lengths
|
|
|
110 |
strL = 128
|
|
|
111 |
DL str, strL # string buf
|
|
|
112 |
EPILOC
|
|
|
113 |
#-----------------------------------------------
|
|
|
114 |
N.init: # c: -->Cnstln
|
|
|
115 |
PROLOG
|
|
|
116 |
mov b, thisP(bp) # save -->this Node
|
|
|
117 |
lea N.debug(b), a
|
|
|
118 |
mov a, deP(bp) # save local -->Debug
|
|
|
119 |
LOG 4, "initializing..."
|
|
|
120 |
# initialize node's attributes
|
|
|
121 |
call getpid
|
|
|
122 |
mov a, N.pid(b)
|
|
|
123 |
mov N.cnstlnP(b), c # -->Constellation
|
|
|
124 |
push deP(bp) # -->caller Debug id
|
|
|
125 |
lea N.data(b), a
|
|
|
126 |
mov a, N.dataP(b)
|
|
|
127 |
push a # -->Data
|
|
|
128 |
call Data # initialize data item
|
|
|
129 |
mov Cn.topo(c), a
|
|
|
130 |
mov a, N.topo(b) # save topology
|
|
|
131 |
mov Cn.ssl(c), a
|
|
|
132 |
mov a, N.ssl(b) # SSL switch
|
|
|
133 |
mov Cn.first(c), a
|
|
|
134 |
mov a, N.first(b) # save port# of first node in constellation
|
|
|
135 |
movl $0, N.kicker(b) # clear kicker switch
|
|
|
136 |
cmp a, N.locPort(b) # kicker ? (locPort == first)
|
|
|
137 |
sete N.kicker(b)
|
|
|
138 |
1: add Cn.nodes(c), a
|
|
|
139 |
dec a
|
|
|
140 |
mov a, N.last(b) # save port# of last node (last = first + nodes -1)
|
|
|
141 |
mov Cn.nodes(c), a
|
|
|
142 |
mov a, N.nodes(b) # save num. of nodes in constellation
|
|
|
143 |
mov Cn.div(c), a
|
|
|
144 |
mov a, N.div(b) # save divisor for random choice (MAX_INT / nodes)
|
|
|
145 |
mov Cn.topo(c), a
|
|
|
146 |
mov a, N.topo(b)
|
|
|
147 |
mov Cn.forwP(c), a
|
|
|
148 |
mov a, N.forwP(b) # save -->shared "forward" indicator
|
|
|
149 |
movl $0, N.closing(b) # unset closing indicator
|
|
|
150 |
# allocate and initialize server side and client side sockets
|
|
|
151 |
mov $SocketInfoL, a
|
|
|
152 |
mull N.nodes(b) # SocketInfo array len
|
|
|
153 |
mov a, N.sockArrLen(b) # save array len
|
|
|
154 |
push a
|
|
|
155 |
call malloc
|
|
|
156 |
cmp $0, a
|
|
|
157 |
jnl 0f
|
|
|
158 |
SYSERR "malloc"
|
|
|
159 |
0: mov thisP(bp), b # -->this Node
|
|
|
160 |
mov a, N.srvSideP(b) # save -->array of server side sockets
|
|
|
161 |
pushl N.sockArrLen(b)
|
|
|
162 |
call malloc
|
|
|
163 |
cmp $0, a
|
|
|
164 |
jnl 0f
|
|
|
165 |
SYSERR "malloc"
|
|
|
166 |
0: mov thisP(bp), b # -->this Node
|
|
|
167 |
mov a, N.cliSideP(b) # save -->array of client side sockets
|
|
|
168 |
# initialize allocated socket infos
|
|
|
169 |
xor c, c # offset
|
|
|
170 |
0: mov N.srvSideP(b), a # -->server side SocketInfo array
|
|
|
171 |
# movl $So.labelV, So.label(a, c) # indicate SocketInfo block
|
|
|
172 |
movl $-1, So.sc(a, c) # indicate server side socket is not in use
|
|
|
173 |
mov N.cliSideP(b), a # -->client side SocketInfo array
|
|
|
174 |
# movl $So.labelV, So.label(a, c) # indicate SocketInfo block
|
|
|
175 |
movl $-1, So.sc(a, c) # indicate client side socket is not in use
|
|
|
176 |
lea SocketInfoL(c), c # incr by SocketInfo len
|
|
|
177 |
cmp c, N.sockArrLen(b)
|
|
|
178 |
ja 0b # iterate
|
|
|
179 |
|
|
|
180 |
cmpl $0, N.ssl(b) # node's ssl switch
|
|
|
181 |
jz N.initR # no SSL
|
|
|
182 |
# prepare SSL context
|
|
|
183 |
# call SSL_load_error_strings
|
|
|
184 |
# call SSL_library_init
|
|
|
185 |
call OPENSSL_init_ssl
|
|
|
186 |
LOG 4, "setting SSL contex...", 0
|
|
|
187 |
call TLS_method
|
|
|
188 |
push a
|
|
|
189 |
call SSL_CTX_new
|
|
|
190 |
mov thisP(bp), b # -->this Node
|
|
|
191 |
mov a, N.ctxP(b) # save -->new SSL context
|
|
|
192 |
test a, a
|
|
|
193 |
jnz 0f
|
|
|
194 |
SSLERR "new SSL CTX"
|
|
|
195 |
# set SSL mode
|
|
|
196 |
0: pushl $0
|
|
|
197 |
pushl $4 # SSL_MODE_AUTO_RETRY
|
|
|
198 |
pushl $33 # SSL_CTRL_MODE
|
|
|
199 |
pushl N.ctxP(b) # -->SSL context
|
|
|
200 |
call SSL_CTX_ctrl
|
|
|
201 |
movl $0, 8(sp) # no callback
|
|
|
202 |
movl $2, 4(sp) # mode = SSL_VERIFY_FAIL_IF_NO_PEER_CERT
|
|
|
203 |
call SSL_CTX_set_verify # set peer certificate verification parameters
|
|
|
204 |
# set X509 key file name
|
|
|
205 |
mov thisP(bp), b # -->this Node
|
|
|
206 |
pushl N.locPort(b) # local TCP port#
|
|
|
207 |
mov C.csP, c
|
|
|
208 |
pushl C.cePathP(c) # -->name of SSL path
|
|
|
209 |
pushl $0f # -->format
|
|
|
210 |
pushl $strL # buf len
|
|
|
211 |
lea str(bp), a
|
|
|
212 |
push a # -->string buf
|
|
|
213 |
call snprintf
|
|
|
214 |
jmp 1f
|
|
|
215 |
0: .asciz "%skeys/%u.key"
|
|
|
216 |
1:
|
|
|
217 |
pushl $1 # SSL_FILETYPE_PEM
|
|
|
218 |
lea str(bp), a # filename string
|
|
|
219 |
push a
|
|
|
220 |
LOG 5, "SSL private key used: %s", 1
|
|
|
221 |
mov thisP(bp), b # -->this Node inst
|
|
|
222 |
pushl N.ctxP(b) # -->SSL context
|
|
|
223 |
call SSL_CTX_use_PrivateKey_file
|
|
|
224 |
cmp $1, a
|
|
|
225 |
je 0f
|
|
|
226 |
SSLERR "hh's key file"
|
|
|
227 |
# set X509 cert file name
|
|
|
228 |
0: mov thisP(bp), b # -->this Node
|
|
|
229 |
pushl N.locPort(b) # local TCP port #
|
|
|
230 |
mov C.csP, c
|
|
|
231 |
pushl C.cePathP(c) # -->name of SSL path
|
|
|
232 |
pushl $0f
|
|
|
233 |
pushl $strL # buf len
|
|
|
234 |
lea str(bp), a # string buf
|
|
|
235 |
push a
|
|
|
236 |
call snprintf
|
|
|
237 |
jmp 1f
|
|
|
238 |
0: .asciz "%scerts/%u.pem"
|
|
|
239 |
1: mov thisP(bp), b # -->this Node
|
|
|
240 |
LOG 5, "SSL certificate used: %s", 1
|
|
|
241 |
pushl $1 # SSL_FILETYPE_PEM
|
|
|
242 |
lea str(bp), a # filename string
|
|
|
243 |
push a
|
|
|
244 |
pushl N.ctxP(b) # -->SSL context
|
|
|
245 |
call SSL_CTX_use_certificate_file
|
|
|
246 |
cmp $1, a
|
|
|
247 |
je 0f
|
|
|
248 |
SSLERR "hh's cert file"
|
|
|
249 |
# set path to CA
|
|
|
250 |
0: mov thisP(bp), b # -->this Node
|
|
|
251 |
mov C.csP, c
|
|
|
252 |
pushl C.caPathP(c) # -->name of SSL path
|
|
|
253 |
pushl $0f # -->CApath
|
|
|
254 |
LOG 5, "SSL: CA path: %s", 1
|
|
|
255 |
pushl $0 # -->CAfile not used
|
|
|
256 |
pushl N.ctxP(b) # -->SSL context
|
|
|
257 |
call SSL_CTX_load_verify_locations # set default locations for trusted CA certificates
|
|
|
258 |
cmp $1, a
|
|
|
259 |
je N.initR
|
|
|
260 |
SSLERR "hh's thrusted certs path"
|
|
|
261 |
0: .asciz "/home/local/etc/ssl/certs/"
|
|
|
262 |
N.initR:
|
|
|
263 |
LOG 5, "initalized"
|
|
|
264 |
EPILOG
|
|
|
265 |
#-----------------------------------------------
|
|
|
266 |
# K I C K O F F
|
|
|
267 |
#-----------------------------------------------
|
|
|
268 |
PROLOC
|
|
|
269 |
DL thisP # -->this Node
|
|
|
270 |
DL deP # -->Debug
|
|
|
271 |
DL sci # socket info rank
|
|
|
272 |
DL digest, 24
|
|
|
273 |
EPILOC
|
|
|
274 |
N.kickOff:
|
|
|
275 |
PROLOG
|
|
|
276 |
mov b, thisP(bp) # save -->this Node
|
|
|
277 |
lea N.debug(b), a
|
|
|
278 |
mov a, deP(bp) # save local -->Debug
|
|
|
279 |
# load payload data
|
|
|
280 |
movl C.csP, c # -->CS
|
|
|
281 |
push C.txtP(c) # -->initial payload text
|
|
|
282 |
push C.ttl(c) # initial TTL
|
|
|
283 |
# lea N.data(b), a # -->Data
|
|
|
284 |
# push a
|
|
|
285 |
push N.dataP(b) # -->Data
|
|
|
286 |
call Da.load # load data container
|
|
|
287 |
call N.nextNode
|
|
|
288 |
mov a, N.next(b) # save next node#
|
|
|
289 |
sub N.first(b), a # first - next = socketinfo rank
|
|
|
290 |
mov a, sci(bp) # save socket info rank
|
|
|
291 |
lea digest(bp), a # -->digest buf
|
|
|
292 |
push a
|
|
|
293 |
push N.dataP(b) # -->Data
|
|
|
294 |
call Da.digest24
|
|
|
295 |
call Da.getDataLen
|
|
|
296 |
push N.next(b) # next node#
|
|
|
297 |
push a # data len
|
|
|
298 |
lea digest(bp), a # -->digest
|
|
|
299 |
push a
|
|
|
300 |
LOG 2, "kicker: ready to initial send %s, len=%u to node %u"
|
|
|
301 |
push N.next(b)
|
|
|
302 |
push sci(bp)
|
|
|
303 |
call N.conn # connect to next node
|
|
|
304 |
push sci(bp)
|
|
|
305 |
call N.put # send data to next node
|
|
|
306 |
EPILOG
|
|
|
307 |
#-----------------------------------------------
|
|
|
308 |
# M A I N L O O P : I T E R A T E O N S O C K E T I / O
|
|
|
309 |
#-----------------------------------------------
|
|
|
310 |
PROLOC
|
|
|
311 |
DL thisP # -->this Node
|
|
|
312 |
DL deP # -->Debug
|
|
|
313 |
EPILOC
|
|
|
314 |
N.mainLoop:
|
|
|
315 |
PROLOG
|
|
|
316 |
mov b, thisP(bp) # save -->this Node
|
|
|
317 |
lea N.debug(b), a
|
|
|
318 |
mov a, deP(bp) # save local -->Debug
|
|
|
319 |
# prepare
|
|
|
320 |
LOG 5, "preparing for I/O select..."
|
|
|
321 |
call N.clearSocketMasks # clear socket masks for select and zero nfds
|
|
|
322 |
call N.maskSsc # mask ssc for select
|
|
|
323 |
# iterate while there are some sockets masked for select (nfds > 0)
|
|
|
324 |
0: cmp $0, N.nfds(b) # any I/O in progress ?
|
|
|
325 |
jz 0f # no, end operations of node
|
|
|
326 |
call N.selectSocketIo # select on server side sockets and forward data
|
|
|
327 |
call N.clearSocketMasks # clear socket masks for select and zero nfds
|
|
|
328 |
call N.maskSsc # mask ssc for select
|
|
|
329 |
call N.maskSrvSockets # mask all connected server side sockets for select
|
|
|
330 |
jmp 0b
|
|
|
331 |
0: EPILOG
|
|
|
332 |
#-----------------------------------------------
|
|
|
333 |
# S E L E C T S O C K E T I / O
|
|
|
334 |
#-----------------------------------------------
|
|
|
335 |
# select on masked sockets
|
|
|
336 |
# upon return from select
|
|
|
337 |
# accept connections to ssc
|
|
|
338 |
# forward data from posted sockets
|
|
|
339 |
#-----------------------------------------------
|
|
|
340 |
PROLOC
|
|
|
341 |
DL thisP # -->this Node
|
|
|
342 |
DL deP # -->Debug
|
|
|
343 |
EPILOC
|
|
|
344 |
N.selectSocketIo:
|
|
|
345 |
PROLOG
|
|
|
346 |
mov b, thisP(bp) # save -->this Node
|
|
|
347 |
lea N.debug(b), a
|
|
|
348 |
mov a, deP(bp) # save local -->Debug
|
|
|
349 |
|
|
|
350 |
push N.nfds(b)
|
|
|
351 |
lea N.rs(b), a
|
|
|
352 |
push (a)
|
|
|
353 |
push 4(a)
|
|
|
354 |
push N.ssc(b)
|
|
|
355 |
LOG 5, "select ssc=%u, mask=%08x %08x, nfds=%u"
|
|
|
356 |
lea N.t(b), a # -->timeval
|
|
|
357 |
movl $1, Ti.secs(a)
|
|
|
358 |
movl $0, Ti.usecs(a)
|
|
|
359 |
push a
|
|
|
360 |
lea N.es(b), a
|
|
|
361 |
push a # -->es (exceptional mask is not used yet)
|
|
|
362 |
pushl $0
|
|
|
363 |
lea N.rs(b), a # -->rs
|
|
|
364 |
push a
|
|
|
365 |
push N.nfds(b)
|
|
|
366 |
SYS select
|
|
|
367 |
lea N.rs(b), a
|
|
|
368 |
push (a)
|
|
|
369 |
push 4(a)
|
|
|
370 |
LOG 5, "return from select, mask of posted=%08x %08x"
|
|
|
371 |
# check ssc for incomming connect request, accept it and forward data
|
|
|
372 |
lea N.rs(b), a # -->rs select mask
|
|
|
373 |
push a
|
|
|
374 |
pushl N.ssc(b)
|
|
|
375 |
call fd_isset
|
|
|
376 |
test a, a # ssc I/O ?
|
|
|
377 |
jz N.checkAndForw # no, check other sockets
|
|
|
378 |
# prepare for accept; find free srv socket info block for accept
|
|
|
379 |
mov N.srvSideP(b), a # -->srv socket info array
|
|
|
380 |
xor c, c # offet in socket info array
|
|
|
381 |
xor d, d # socket info rank
|
|
|
382 |
0: cmp $-1, So.sc(a, c) # socket allocated ?
|
|
|
383 |
je 0f # no, free socket found
|
|
|
384 |
inc d
|
|
|
385 |
lea SocketInfoL(c), c # inc offset into array
|
|
|
386 |
cmp c, N.sockArrLen(b)
|
|
|
387 |
ja 0b # iterate on sockets
|
|
|
388 |
ERR "can't accept, all sockets in use"
|
|
|
389 |
# free socket found, accept connection on it and forward data
|
|
|
390 |
0: push d
|
|
|
391 |
LOG 4, "slot for accept=%d"
|
|
|
392 |
call N.acc
|
|
|
393 |
call N.forw
|
|
|
394 |
# check all server side sockets for pending I/O and call forward on them
|
|
|
395 |
N.checkAndForw:
|
|
|
396 |
xor c, c # offet into socket info array
|
|
|
397 |
lea N.rs(b), a # -->rs select mask
|
|
|
398 |
push a
|
|
|
399 |
lea -4(sp), sp # adjust stacker for iteration
|
|
|
400 |
xor c, c # zero offset
|
|
|
401 |
xor d, d # set counter
|
|
|
402 |
# iterate through server side sockets and forward from posted sockets
|
|
|
403 |
0: mov N.srvSideP(b), a # -->srv socket info array
|
|
|
404 |
cmp $-1, So.sc(a, c) # socket connected ?
|
|
|
405 |
je 1f # no, iterate
|
|
|
406 |
mov So.sc(a, c), a
|
|
|
407 |
mov a, (sp) # stack socket#
|
|
|
408 |
# LOG 0, "checking port %u"
|
|
|
409 |
call fd_isset # socket I/O ?
|
|
|
410 |
test a, a
|
|
|
411 |
jz 1f # no, iterate
|
|
|
412 |
mov N.srvSideP(b), a
|
|
|
413 |
mov So.sc(a, c), a
|
|
|
414 |
mov d, (sp) # stack socket rank
|
|
|
415 |
# LOG 0, "port posted, rank=%u"
|
|
|
416 |
call N.forw # forward data
|
|
|
417 |
1: inc d
|
|
|
418 |
lea SocketInfoL(c), c # inc offset into array
|
|
|
419 |
cmp c, N.sockArrLen(b)
|
|
|
420 |
ja 0b # iterate on srv side sockets
|
|
|
421 |
EPILOG
|
|
|
422 |
#-----------------------------------------------
|
|
|
423 |
# M A S K C O N N E C T E D S O C K E T S F O R S E L E C T
|
|
|
424 |
#-----------------------------------------------
|
|
|
425 |
# mask all connected server side socketS for next select
|
|
|
426 |
PROLOC
|
|
|
427 |
DL thisP # -->this Node
|
|
|
428 |
EPILOC
|
|
|
429 |
N.maskSrvSockets:
|
|
|
430 |
PROLOG
|
|
|
431 |
mov b, thisP(bp) # save -->this Node
|
|
|
432 |
|
|
|
433 |
lea N.rs(b), a # -->rs select mask
|
|
|
434 |
push a
|
|
|
435 |
lea -4(sp), sp # adjust stacker for iteration
|
|
|
436 |
xor c, c # zero offet
|
|
|
437 |
0: mov N.srvSideP(b), a # -->srv socket info array
|
|
|
438 |
cmp $-1, So.sc(a, c) # socket connected ?
|
|
|
439 |
je 1f # no, iterate
|
|
|
440 |
mov So.sc(a, c), a
|
|
|
441 |
mov a, (sp) # stack socket#
|
|
|
442 |
call N.maskSocket # mask socket for select
|
|
|
443 |
1: lea SocketInfoL(c), c # inc offset into array
|
|
|
444 |
cmp c, N.sockArrLen(b)
|
|
|
445 |
ja 0b # iterate on srv side sockets
|
|
|
446 |
EPILOG
|
|
|
447 |
#-----------------------------------------------
|
|
|
448 |
# M A S K S S C F O R S E L E C T
|
|
|
449 |
#-----------------------------------------------
|
|
|
450 |
# mask ssc for select until forward is disabled
|
|
|
451 |
PROLOC
|
|
|
452 |
DL thisP # -->this Node
|
|
|
453 |
EPILOC
|
|
|
454 |
N.maskSsc:
|
|
|
455 |
PROLOG
|
|
|
456 |
mov b, thisP(bp) # save -->this Node
|
|
|
457 |
|
|
|
458 |
mov N.forwP(b), a
|
|
|
459 |
cmp $1, (a) # forwarding enabled ?
|
|
|
460 |
jne 0f # no, return
|
|
|
461 |
push N.ssc(b)
|
|
|
462 |
call N.maskSocket
|
|
|
463 |
0: EPILOG
|
|
|
464 |
#-----------------------------------------------
|
|
|
465 |
# C L E A R S O C K E T M A S K S
|
|
|
466 |
#-----------------------------------------------
|
|
|
467 |
PROLOC
|
|
|
468 |
DL thisP # -->this Node
|
|
|
469 |
EPILOC
|
|
|
470 |
N.clearSocketMasks:
|
|
|
471 |
PROLOG
|
|
|
472 |
mov b, thisP(bp) # save -->this Node
|
|
|
473 |
|
|
|
474 |
movl $0, N.nfds(b) # zero nfds
|
|
|
475 |
lea N.rs(b), a # zero rs select mask
|
|
|
476 |
push a
|
|
|
477 |
call fd_zero
|
|
|
478 |
lea N.es(b), a # zero es select masks
|
|
|
479 |
push a
|
|
|
480 |
call fd_zero
|
|
|
481 |
EPILOG
|
|
|
482 |
#-----------------------------------------------
|
|
|
483 |
# M A S K S O C K E T F O R S E L E C T
|
|
|
484 |
#-----------------------------------------------
|
|
|
485 |
ARGS
|
|
|
486 |
DS sc # socket#
|
|
|
487 |
PROLOC
|
|
|
488 |
DL thisP # -->this Node
|
|
|
489 |
EPILOC
|
|
|
490 |
N.maskSocket:
|
|
|
491 |
PROLOG
|
|
|
492 |
mov b, thisP(bp) # save -->this Node
|
|
|
493 |
|
|
|
494 |
lea N.rs(b), a # -->rs select mask
|
|
|
495 |
push a
|
|
|
496 |
pushl sc(bp)
|
|
|
497 |
call fd_set
|
|
|
498 |
mov sc(bp), a # socket#
|
|
|
499 |
cmp a, N.nfds(b) # nfds > sc ?
|
|
|
500 |
jg 0f # yes
|
|
|
501 |
inc a
|
|
|
502 |
mov a, N.nfds(b) # nfds = sc + 1
|
|
|
503 |
0: EPILOG
|
|
|
504 |
#-----------------------------------------------
|
|
|
505 |
# F D S E T O P E R A T I N O S
|
|
|
506 |
#-----------------------------------------------
|
|
|
507 |
PROLOC # local data frame def. is used by 4 following subrs
|
|
|
508 |
DL thisP # -->this Node
|
|
|
509 |
dL deP
|
|
|
510 |
EPILOC
|
|
|
511 |
fd_zero:
|
|
|
512 |
# zero FD mask
|
|
|
513 |
ARGS
|
|
|
514 |
DS fdsetP # -->FD mask
|
|
|
515 |
PROLOG
|
|
|
516 |
mov fdsetP(bp), a
|
|
|
517 |
xor c, c
|
|
|
518 |
0: movl $0, (a, c, 4)
|
|
|
519 |
inc c
|
|
|
520 |
cmp $32, c # size of FD mask is 32 int (1024 bits)
|
|
|
521 |
jl 0b
|
|
|
522 |
EPILOG
|
|
|
523 |
fd_set:
|
|
|
524 |
# mask socket in FD mask
|
|
|
525 |
ARGS
|
|
|
526 |
DS sc
|
|
|
527 |
DS fdsetP # -->FD mask
|
|
|
528 |
PROLOG
|
|
|
529 |
movl sc(bp), a # sc
|
|
|
530 |
call fd_mask # a: integer offset, d: "1" bit in position according to sc
|
|
|
531 |
mov fdsetP(bp), c # -->select mask
|
|
|
532 |
or d, (c, a) # set sc mask
|
|
|
533 |
EPILOG
|
|
|
534 |
fd_clear:
|
|
|
535 |
# clear socket from FD mask
|
|
|
536 |
ARGS
|
|
|
537 |
DS sc
|
|
|
538 |
DS fdsetP # -->FD mask
|
|
|
539 |
PROLOG
|
|
|
540 |
movl sc(bp), a # sc
|
|
|
541 |
call fd_mask # a: integer offset, d: "1" bit in position according to sc
|
|
|
542 |
mov fdsetP(bp), c # -->select mask
|
|
|
543 |
not d
|
|
|
544 |
and d, (c, a) # clear sc mask
|
|
|
545 |
EPILOG
|
|
|
546 |
fd_isset:
|
|
|
547 |
# test socket bit status in FD mask
|
|
|
548 |
ARGS
|
|
|
549 |
DS sc
|
|
|
550 |
DS fdsetP # -->FD mask
|
|
|
551 |
PROLOG
|
|
|
552 |
movl sc(bp), a # sc
|
|
|
553 |
call fd_mask # a: integer offset, d: "1" bit in position according to sc
|
|
|
554 |
mov fdsetP(bp), c # -->select mask
|
|
|
555 |
and (c, a), d # sc selected ?
|
|
|
556 |
mov d, a
|
|
|
557 |
# mov $0, a
|
|
|
558 |
# jz 0f # not selected
|
|
|
559 |
# mov $1, a
|
|
|
560 |
0: EPILOG_R
|
|
|
561 |
fd_mask: # a: sc
|
|
|
562 |
# adjust offsets into FD mask
|
|
|
563 |
xor d, d
|
|
|
564 |
movl $32, c
|
|
|
565 |
divl c # a: mask integer rank, c: bit offset
|
|
|
566 |
shll $2, a # a: mask integer offset
|
|
|
567 |
mov d, c
|
|
|
568 |
mov $1, d
|
|
|
569 |
shl %cl, d # d: "1" bit in position according to sc
|
|
|
570 |
ret # a: offset of mask integer
|
|
|
571 |
#-----------------------------------------------
|
|
|
572 |
# F O R W A R D D A T A T O O T H E R N O D E
|
|
|
573 |
#-----------------------------------------------
|
|
|
574 |
ARGS
|
|
|
575 |
DS sci # SocketInfo rank
|
|
|
576 |
PROLOC
|
|
|
577 |
DL thisP # -->this Node
|
|
|
578 |
DL deP # -->Debug inst
|
|
|
579 |
DL digest, 24
|
|
|
580 |
EPILOC
|
|
|
581 |
#-----------------------------------------------
|
|
|
582 |
N.forw:
|
|
|
583 |
PROLOG
|
|
|
584 |
mov b, thisP(bp) # save -->this Node
|
|
|
585 |
lea N.debug(b), a
|
|
|
586 |
mov a, deP(bp) # save local -->Debug
|
|
|
587 |
|
|
|
588 |
push sci(bp) # socket info rank
|
|
|
589 |
call N.get
|
|
|
590 |
test a, a # data read ?
|
|
|
591 |
jz N.forwCloseSock # no, EOF, close this socket and start closing clients
|
|
|
592 |
# kicker checks TTL
|
|
|
593 |
cmp $1, N.kicker(b) # kicker ?
|
|
|
594 |
jne 1f # no, continue forwarding
|
|
|
595 |
|
|
|
596 |
lea -4(sp), sp # adjust stacker
|
|
|
597 |
lea digest(bp), a
|
|
|
598 |
push a # -->digest buf
|
|
|
599 |
push N.dataP(b) # -->Data
|
|
|
600 |
call Da.ttl
|
|
|
601 |
mov a, 8(sp) # TTL from data header
|
|
|
602 |
call Da.digest24
|
|
|
603 |
mov a, 4(sp) # -->text digest
|
|
|
604 |
call Da.getPort
|
|
|
605 |
mov a, (sp) # remote listen port from data header
|
|
|
606 |
LOG 5, "received from node %u: %s, ttl=%d"
|
|
|
607 |
push N.dataP(b) # -->Data
|
|
|
608 |
call Da.dttl # decrement TTL in data
|
|
|
609 |
test a, a # TTl > 0 ?
|
|
|
610 |
jz N.forwKickerStop # no, disable forwarding in constellation
|
|
|
611 |
# forward data
|
|
|
612 |
1: call N.nextNode # calculate next node
|
|
|
613 |
mov a, N.next(b)
|
|
|
614 |
push a
|
|
|
615 |
LOG 4, "next node %u"
|
|
|
616 |
sub N.first(b), a # socket info rank (next - first)
|
|
|
617 |
mov a, sci(bp) # save
|
|
|
618 |
# connect if not connected yet
|
|
|
619 |
movl $SocketInfoL, d
|
|
|
620 |
mul d # a: offset into socket info array
|
|
|
621 |
mov N.cliSideP(b), c # -->client side socket info array
|
|
|
622 |
cmp $-1, So.sc(c, a) # connected ?
|
|
|
623 |
jne 0f # yes
|
|
|
624 |
push N.next(b)
|
|
|
625 |
push sci(bp)
|
|
|
626 |
call N.conn
|
|
|
627 |
0:
|
|
|
628 |
lea -4(sp), sp
|
|
|
629 |
push N.dataP(b) # -->Data
|
|
|
630 |
call Da.ttl
|
|
|
631 |
mov a, 4(sp) # ttl
|
|
|
632 |
call Da.getDataLen
|
|
|
633 |
mov a, (sp) # container len
|
|
|
634 |
push N.next(b) # next node#
|
|
|
635 |
LOG 5, "forwarding to %d, len=%d, ttl=%d --->"
|
|
|
636 |
# pacing
|
|
|
637 |
mov C.csP, c # -->CS
|
|
|
638 |
cmp $0, C.pacing(c) # pacing active ?
|
|
|
639 |
je 0f # no
|
|
|
640 |
pushl $0
|
|
|
641 |
lea C.pace.tv_sec(c), a
|
|
|
642 |
push a
|
|
|
643 |
SYS nanosleep # pace
|
|
|
644 |
0: push sci(bp)
|
|
|
645 |
call N.put
|
|
|
646 |
LOG 4, "leaving forward"
|
|
|
647 |
jmp N.forwR # exit forwarding
|
|
|
648 |
N.forwKickerStop: # ttl = 0
|
|
|
649 |
lea digest(bp), a
|
|
|
650 |
push a # -->digest buf
|
|
|
651 |
push N.dataP(b) # -->Data
|
|
|
652 |
call Da.digest24
|
|
|
653 |
push a
|
|
|
654 |
LOG 1, "received after finally passing all: %s", 1
|
|
|
655 |
mov N.forwP(b), a # -->shared forw indicator
|
|
|
656 |
movl $0, (a) # disable forwarding for all nodes in constellation
|
|
|
657 |
jmp N.forwCloseCli
|
|
|
658 |
N.forwCloseSock:
|
|
|
659 |
pushl deP(bp)
|
|
|
660 |
pushl $1 # indicate "server side"
|
|
|
661 |
push sci(bp) # socket info rank
|
|
|
662 |
call N.closeSocket # close this server side socket
|
|
|
663 |
N.forwCloseCli:
|
|
|
664 |
call N.closeClients # launch client side closing thread
|
|
|
665 |
LOG 4, "leaving forward, closing"
|
|
|
666 |
N.forwR:
|
|
|
667 |
EPILOG
|
|
|
668 |
#-----------------------------------------------
|
|
|
669 |
# D E T E R M I N E N E X T N O D E
|
|
|
670 |
#-----------------------------------------------
|
|
|
671 |
PROLOC
|
|
|
672 |
DL thisP # -->this Node
|
|
|
673 |
EPILOC
|
|
|
674 |
N.nextNode:
|
|
|
675 |
PROLOG
|
|
|
676 |
mov b, thisP(bp) # save -->this Node
|
|
|
677 |
|
|
|
678 |
cmp $Cn.ring, N.topo(b) # ring ?
|
|
|
679 |
jne 0f # no
|
|
|
680 |
# ring
|
|
|
681 |
mov N.locPort(b), a
|
|
|
682 |
inc a # next = locPort + 1
|
|
|
683 |
cmp a, N.last(b) # next > last ?
|
|
|
684 |
jnl N.nextNodeR
|
|
|
685 |
mov N.first(b), a
|
|
|
686 |
jmp N.nextNodeR
|
|
|
687 |
# mash
|
|
|
688 |
0: call random
|
|
|
689 |
xor d, d
|
|
|
690 |
mov thisP(bp), b
|
|
|
691 |
divl N.div(b) # 0 <= random < nodes
|
|
|
692 |
add N.first(b), a # first + random
|
|
|
693 |
cmp a, N.locPort(b)
|
|
|
694 |
je 0b # iterate until other then local node is selected
|
|
|
695 |
N.nextNodeR:
|
|
|
696 |
push a
|
|
|
697 |
EPILOG_R
|
|
|
698 |
|
|
|
699 |
#-----------------------------------------------
|
|
|
700 |
# B I N D T O L O C A L T C P P O R T
|
|
|
701 |
#-----------------------------------------------
|
|
|
702 |
# returns
|
|
|
703 |
# nothing
|
|
|
704 |
PROLOC
|
|
|
705 |
DL thisP # -->this Node
|
|
|
706 |
DL deP # -->Debug
|
|
|
707 |
DL i
|
|
|
708 |
DL aiP # -->IP addrinfo
|
|
|
709 |
strL = 64
|
|
|
710 |
DL str, strL # string buf
|
|
|
711 |
EPILOC
|
|
|
712 |
#-----------------------------------------------
|
|
|
713 |
.global N.bind
|
|
|
714 |
N.bind:
|
|
|
715 |
PROLOG
|
|
|
716 |
mov b, thisP(bp) # save -->this Node
|
|
|
717 |
lea N.debug(b), a
|
|
|
718 |
mov a, deP(bp) # save local -->Debug
|
|
|
719 |
LOG 4, "binding...", 0
|
|
|
720 |
# prepare IP addr
|
|
|
721 |
pushl $AddrInfoL
|
|
|
722 |
call malloc # alloc addrinfo for hints
|
|
|
723 |
mov a, aiP(bp)
|
|
|
724 |
pushl $AddrInfoL
|
|
|
725 |
pushl $0
|
|
|
726 |
push a
|
|
|
727 |
call memset # clear hints
|
|
|
728 |
|
|
|
729 |
movl $2, ai_family(a) # AF_INET
|
|
|
730 |
movl $1, ai_flags(a) # AI_PASSIVE for bind
|
|
|
731 |
movl $0, ai_protocol(a) # any protocol
|
|
|
732 |
movl $1, ai_socktype(a) # SOCK_STREAM, blocking type
|
|
|
733 |
|
|
|
734 |
mov thisP(bp), b # -->this Node
|
|
|
735 |
pushl N.locPort(b) # local port #
|
|
|
736 |
push $0f
|
|
|
737 |
lea str(bp), a
|
|
|
738 |
push a # -->str buff
|
|
|
739 |
call sprintf
|
|
|
740 |
jmp 1f
|
|
|
741 |
0: .ascii "%d\0"
|
|
|
742 |
1:
|
|
|
743 |
lea aiP(bp), a
|
|
|
744 |
push a # -->-->addrinfo for new addrinfo
|
|
|
745 |
pushl aiP(bp) # -->addrinfo hints
|
|
|
746 |
lea str(bp), a
|
|
|
747 |
push a # -->loc port # string
|
|
|
748 |
pushl $0f
|
|
|
749 |
call getaddrinfo
|
|
|
750 |
jmp 1f
|
|
|
751 |
0: .ascii "localhost\0"
|
|
|
752 |
# check IP addr
|
|
|
753 |
1: cmp $0, a # getaddrinfo OK ?
|
|
|
754 |
jz 0f # yes
|
|
|
755 |
push a
|
|
|
756 |
call gai_strerror
|
|
|
757 |
push a
|
|
|
758 |
LOG 0, "getaddrinfo error: %s, ABEND", 1
|
|
|
759 |
push $1
|
|
|
760 |
call exit
|
|
|
761 |
# log assigned IP addr
|
|
|
762 |
0: pushl deP(bp)
|
|
|
763 |
mov aiP(bp), a # -->addrinfo
|
|
|
764 |
pushl ai_addrP(a) # -->sockaddr
|
|
|
765 |
lea str(bp), a
|
|
|
766 |
push a # -->string buf
|
|
|
767 |
call gai
|
|
|
768 |
|
|
|
769 |
lea str(bp), a
|
|
|
770 |
push a
|
|
|
771 |
LOG 5, "getaddrinfo OK, %s", 1
|
|
|
772 |
# allocate socket
|
|
|
773 |
mov aiP(bp), a
|
|
|
774 |
pushl ai_protocol(a)
|
|
|
775 |
pushl ai_socktype(a)
|
|
|
776 |
pushl ai_family(a)
|
|
|
777 |
SYS socket
|
|
|
778 |
mov a, N.ssc(b) # save ssc
|
|
|
779 |
# set socket option SO_REUSEADDR
|
|
|
780 |
pushl $4 # integer width
|
|
|
781 |
lea 9f, a # value 1
|
|
|
782 |
push a
|
|
|
783 |
pushl $2 # SO_REUSEADDR
|
|
|
784 |
pushl $1 # SOL_SOCKET
|
|
|
785 |
push N.ssc(b) # ssc
|
|
|
786 |
SYS setsockopt
|
|
|
787 |
jmp 8f
|
|
|
788 |
9: .long 1
|
|
|
789 |
8:
|
|
|
790 |
# bind
|
|
|
791 |
mov aiP(bp), a
|
|
|
792 |
pushl ai_addrlen(a)
|
|
|
793 |
pushl ai_addrP(a)
|
|
|
794 |
push N.ssc(b) # ssc
|
|
|
795 |
SYS bind
|
|
|
796 |
# listen
|
|
|
797 |
pushl $1 # pend conns queue len
|
|
|
798 |
pushl N.ssc(b) # ssc
|
|
|
799 |
SYS listen
|
|
|
800 |
pushl N.locPort(b)
|
|
|
801 |
LOG 2, "bound to %d", 1
|
|
|
802 |
N.bindR:
|
|
|
803 |
EPILOG
|
|
|
804 |
#-----------------------------------------------
|
|
|
805 |
# C O N N E C T T O R E M O T E N O D E
|
|
|
806 |
#-----------------------------------------------
|
|
|
807 |
# args
|
|
|
808 |
ac = 40
|
|
|
809 |
DS i # socket rank
|
|
|
810 |
DS remPort # TCP port# on remote site
|
|
|
811 |
# returns
|
|
|
812 |
# nothing
|
|
|
813 |
# local vars
|
|
|
814 |
ac = 0
|
|
|
815 |
DL debug, DebugL # Debug inst
|
|
|
816 |
DL deP # -->Debug inst
|
|
|
817 |
DL retry # retry counter
|
|
|
818 |
DL ai, AddrInfoL # IP addrinfo
|
|
|
819 |
DL aiP # -->IP addrinfo
|
|
|
820 |
DL str, 64 # string buf
|
|
|
821 |
DL currSockP # -->SocketInfo save area
|
|
|
822 |
locL = ac
|
|
|
823 |
#-----------------------------------------------
|
|
|
824 |
.global N.conn
|
|
|
825 |
N.conn:
|
|
|
826 |
PROLOG
|
|
|
827 |
mov b, thisP(bp) # save -->this Node
|
|
|
828 |
lea debug(bp), a # -->own local debug block
|
|
|
829 |
mov a, deP(bp) # save -->local Debug
|
|
|
830 |
pushl remPort(bp) # remote port
|
|
|
831 |
lea N.debug(b), d # -->node's Debug
|
|
|
832 |
lea D.id(d), a # -->node's debug ID
|
|
|
833 |
push a
|
|
|
834 |
DEBID "%s to %u", 2 # set local debug ID
|
|
|
835 |
LOG 3, "connecting...", 0
|
|
|
836 |
|
|
|
837 |
mov N.cliSideP(b), c # -->SocketInfo array
|
|
|
838 |
mov $SocketInfoL, a
|
|
|
839 |
mull i(bp) # SocketInfo offset
|
|
|
840 |
lea (c, a), c # -->curr SocketInfo
|
|
|
841 |
mov c, currSockP(bp) # save -->curr SocketInfo
|
|
|
842 |
mov remPort(bp), a
|
|
|
843 |
mov a, So.remPort(c) # put remote port # into curr SocketInfo
|
|
|
844 |
# prepare IP addrinfo hints
|
|
|
845 |
pushl $AddrInfoL # IP addrinfo length
|
|
|
846 |
pushl $0
|
|
|
847 |
lea ai(bp), a
|
|
|
848 |
mov a, aiP(bp) # -->IP addrinfo
|
|
|
849 |
push a
|
|
|
850 |
call memset # clear addrinfo
|
|
|
851 |
movl $2, ai_family(a) # AF_INET
|
|
|
852 |
movl $0, ai_flags(a)
|
|
|
853 |
movl $0, ai_protocol(a) # any protocol
|
|
|
854 |
movl $1, ai_socktype(a) # SOCK_STREAM
|
|
|
855 |
# set up port # string
|
|
|
856 |
mov currSockP(bp), a # -->curr socket info
|
|
|
857 |
pushl So.remPort(a) # remote port#
|
|
|
858 |
pushl $0f
|
|
|
859 |
lea str(bp), a
|
|
|
860 |
push a # -->port# string
|
|
|
861 |
call sprintf
|
|
|
862 |
jmp 1f
|
|
|
863 |
0: .ascii "%u\0"
|
|
|
864 |
# get IP addrinfo block chain
|
|
|
865 |
1: lea aiP(bp), a # -->-->IP addrinfo
|
|
|
866 |
push a
|
|
|
867 |
pushl aiP(bp) # -->IP addrinfo hints
|
|
|
868 |
lea str(bp), a # -->remote port # string
|
|
|
869 |
push a
|
|
|
870 |
pushl $0f
|
|
|
871 |
call getaddrinfo
|
|
|
872 |
jmp 1f
|
|
|
873 |
0: .ascii "localhost\0"
|
|
|
874 |
# check IP addr
|
|
|
875 |
1: cmp $0, a # getaddrinfo OK ?
|
|
|
876 |
jz 0f # yes
|
|
|
877 |
push a
|
|
|
878 |
call gai_strerror
|
|
|
879 |
push a
|
|
|
880 |
LOG 0, "getaddrinfo error: %s, ABEND", 1
|
|
|
881 |
push $1
|
|
|
882 |
call exit # ABEND
|
|
|
883 |
# log assigned IP addr
|
|
|
884 |
0: pushl deP(bp) # -->Debug inst
|
|
|
885 |
mov aiP(bp), a # -->IP addrinfo
|
|
|
886 |
pushl ai_addrP(a) # -->sockaddr
|
|
|
887 |
lea str(bp), a
|
|
|
888 |
push a # -->string buf
|
|
|
889 |
call gai
|
|
|
890 |
LOG 5, "getaddrinfo OK, %s", 1
|
|
|
891 |
# allocate comm socket
|
|
|
892 |
mov aiP(bp), a # -->IP addrinfo
|
|
|
893 |
pushl ai_protocol(a)
|
|
|
894 |
pushl ai_socktype(a)
|
|
|
895 |
pushl ai_family(a)
|
|
|
896 |
# call socket # allocate comm socket
|
|
|
897 |
# cmp $0, a
|
|
|
898 |
# jg 0f
|
|
|
899 |
# SYSERR "socket alloc"
|
|
|
900 |
#0:
|
|
|
901 |
SYS socket
|
|
|
902 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
903 |
mov a, So.sc(c) # put new socket # into SocketInfo
|
|
|
904 |
# connect to remote partner server side
|
|
|
905 |
mov C.csP, a
|
|
|
906 |
mov C.connTh(a), a # conn retry threshold
|
|
|
907 |
mov a, retry(bp) # initilize retry counter
|
|
|
908 |
mov aiP(bp), a # -->IP addrinfo
|
|
|
909 |
pushl ai_addrlen(a)
|
|
|
910 |
pushl ai_addrP(a)
|
|
|
911 |
pushl So.sc(c) # socket #
|
|
|
912 |
2: call connect
|
|
|
913 |
cmp $0, a
|
|
|
914 |
jnl 0f # connected
|
|
|
915 |
call __errno_location # get --> sys errno
|
|
|
916 |
cmp $111, (a) # ECONNREFUSED ?
|
|
|
917 |
je 1f # yes, wait to retry
|
|
|
918 |
SYSERR "connect" # no, ABEND
|
|
|
919 |
1: pushl $22000 # 22 msecs
|
|
|
920 |
call usleep
|
|
|
921 |
lea 4(sp), sp
|
|
|
922 |
sub $1, retry(bp)
|
|
|
923 |
jnz 2b # iterate
|
|
|
924 |
# conn retry threshold reached
|
|
|
925 |
mov C.csP, a
|
|
|
926 |
pushl C.connTh(a)
|
|
|
927 |
LOG 0, "connection refused, threshold %d reached", 1
|
|
|
928 |
pushl $1
|
|
|
929 |
call exit # ABEND
|
|
|
930 |
0:
|
|
|
931 |
# connected, account new connection
|
|
|
932 |
mov C.csP, c # -->CS
|
|
|
933 |
mov C.shP(c), a # -->shared mem
|
|
|
934 |
lea S.counter_sem(a), a # -->overall counter semaphore
|
|
|
935 |
push a
|
|
|
936 |
SYS sem_wait
|
|
|
937 |
mov C.csP, c # -->CS
|
|
|
938 |
mov C.shP(c), a # -->shared mem
|
|
|
939 |
incl S.conns(a) # incr conns counter
|
|
|
940 |
lea S.counter_sem(a), a # -->overall msg counter semaphore
|
|
|
941 |
push a
|
|
|
942 |
SYS sem_post
|
|
|
943 |
# prepare SSL
|
|
|
944 |
cmp $1, N.ssl(b) # node's ssl switch
|
|
|
945 |
jne N.connRet # no SSL
|
|
|
946 |
|
|
|
947 |
LOG 5, "prepare for SSL"
|
|
|
948 |
pushl N.ctxP(b) # -->SSL context
|
|
|
949 |
call SSL_new # create a SSL structure
|
|
|
950 |
|
|
|
951 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
952 |
mov a, So.sslP(c) # put -->SSL struct into SocketInfo
|
|
|
953 |
test a, a
|
|
|
954 |
jnz 0f
|
|
|
955 |
SSLERR "new SSL"
|
|
|
956 |
# connect on SSL
|
|
|
957 |
0: call ERR_clear_error
|
|
|
958 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
959 |
pushl So.sc(c) # socket
|
|
|
960 |
pushl So.sslP(c) # -->SSL struct
|
|
|
961 |
call SSL_set_fd # connect the SSL object with a file descriptor
|
|
|
962 |
test a, a
|
|
|
963 |
jnz 0f
|
|
|
964 |
SSLERR "client SSL set fd"
|
|
|
965 |
0:
|
|
|
966 |
LOG 5, "SSL fd set"
|
|
|
967 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
968 |
pushl So.sslP(c) # -->SSL struct
|
|
|
969 |
call SSL_connect
|
|
|
970 |
test a, a # connected ?
|
|
|
971 |
jns 1f # yes
|
|
|
972 |
push a
|
|
|
973 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
974 |
pushl So.sslP(c) # -->SSL struct
|
|
|
975 |
call SSL_get_error # SSL_get_error(-->ssl, err)
|
|
|
976 |
cmp $5, a # SSL_ERROR_SYSCALL ?
|
|
|
977 |
jne 0f # no, other SSL err
|
|
|
978 |
SYSERR "SSL connect"
|
|
|
979 |
0: SSLERR "SSL connect"
|
|
|
980 |
1:
|
|
|
981 |
mov C.csP, a
|
|
|
982 |
mov C.connTh(a), a
|
|
|
983 |
sub retry(bp), a # # of retries = conn threshold - counter
|
|
|
984 |
push a
|
|
|
985 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
986 |
pushl So.sc(c) # socket#
|
|
|
987 |
LOG 2, "connected via sc=%d after %d retries", 2
|
|
|
988 |
N.connRet:
|
|
|
989 |
EPILOG
|
|
|
990 |
#-----------------------------------------------
|
|
|
991 |
# A C C E P T C O N N E C T I O N
|
|
|
992 |
#-----------------------------------------------
|
|
|
993 |
ARGS
|
|
|
994 |
DS i # socket rank
|
|
|
995 |
# returns
|
|
|
996 |
# nothing
|
|
|
997 |
# local vars
|
|
|
998 |
PROLOC
|
|
|
999 |
DL thisP # -->this Node
|
|
|
1000 |
DL deP # -->Debug inst
|
|
|
1001 |
DL sa, SockAddrL # sockaddr
|
|
|
1002 |
DL str, 64 # string buf
|
|
|
1003 |
DL currSockP # -->curr SocketInfo save area
|
|
|
1004 |
EPILOC
|
|
|
1005 |
#-----------------------------------------------
|
|
|
1006 |
.global N.acc
|
|
|
1007 |
N.acc:
|
|
|
1008 |
PROLOG
|
|
|
1009 |
mov b, thisP(bp) # save -->this Node
|
|
|
1010 |
lea N.debug(b), a
|
|
|
1011 |
mov a, deP(bp) # save local -->Debug
|
|
|
1012 |
LOG 4, "accepting..."
|
|
|
1013 |
|
|
|
1014 |
mov N.srvSideP(b), c # -->SocketInfo array
|
|
|
1015 |
mov $SocketInfoL, a
|
|
|
1016 |
mull i(bp) # curr SocketInfo offset
|
|
|
1017 |
lea (c, a), a # -->curr SocketInfo
|
|
|
1018 |
mov a, currSockP(bp) # save -->curr SocketInfo
|
|
|
1019 |
# accept
|
|
|
1020 |
pushl $0
|
|
|
1021 |
pushl $0
|
|
|
1022 |
# mov thisP, b # -->Node inst
|
|
|
1023 |
pushl N.ssc(b) # listen socket
|
|
|
1024 |
# call accept
|
|
|
1025 |
# cmp $0, a
|
|
|
1026 |
# jnl 0f
|
|
|
1027 |
# SYSERR "accept"
|
|
|
1028 |
#0:
|
|
|
1029 |
SYS accept
|
|
|
1030 |
mov currSockP(bp), c # -->Node inst
|
|
|
1031 |
mov a, So.sc(c) # save comm socket of accepted connection
|
|
|
1032 |
pushl $0f # -->sa length
|
|
|
1033 |
lea sa(bp), a # -->sockaddr
|
|
|
1034 |
push a
|
|
|
1035 |
pushl So.sc(c) # comm socket
|
|
|
1036 |
call getpeername
|
|
|
1037 |
jmp 1f
|
|
|
1038 |
0: .int SockAddrL
|
|
|
1039 |
1: pushl deP(bp)
|
|
|
1040 |
lea sa(bp), a # -->sockaddr
|
|
|
1041 |
push a
|
|
|
1042 |
lea str(bp), a # -->string buf
|
|
|
1043 |
push a
|
|
|
1044 |
call gai # get string of addr/port
|
|
|
1045 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
1046 |
pushl So.sc(c) # comm socket
|
|
|
1047 |
LOG 3, "peer: sc=%d, %s", 2
|
|
|
1048 |
# prepare SSL
|
|
|
1049 |
mov thisP(bp), b # -->this Node
|
|
|
1050 |
cmp $1, N.ssl(b) # node's ssl switch
|
|
|
1051 |
jne 1f # no SSL
|
|
|
1052 |
|
|
|
1053 |
pushl N.ctxP(b) # -->SSL context
|
|
|
1054 |
call SSL_new # create a SSL structure
|
|
|
1055 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
1056 |
mov a, So.sslP(c) # put -->SSL struct into SocketInfo
|
|
|
1057 |
test a, a
|
|
|
1058 |
jnz 0f
|
|
|
1059 |
SSLERR "new SSL"
|
|
|
1060 |
# accept on SSL
|
|
|
1061 |
0: call ERR_clear_error
|
|
|
1062 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
1063 |
pushl So.sc(c) # socket #
|
|
|
1064 |
pushl So.sslP(c) # -->SSL struct
|
|
|
1065 |
call SSL_set_fd # connect the SSL object with a file descriptor
|
|
|
1066 |
test a, a
|
|
|
1067 |
jnz 0f
|
|
|
1068 |
SSLERR "client SSL set fd"
|
|
|
1069 |
0:
|
|
|
1070 |
LOG 5, "SSL fd set"
|
|
|
1071 |
call SSL_accept
|
|
|
1072 |
test a, a
|
|
|
1073 |
jns 1f
|
|
|
1074 |
mov a, 4(sp)
|
|
|
1075 |
call SSL_get_error # SSL_get_error(-->ssl, err)
|
|
|
1076 |
cmp $5, a # SSL_ERROR_SYSCALL ?
|
|
|
1077 |
jne 0f # no, other SSL err
|
|
|
1078 |
SYSERR "SSL accept"
|
|
|
1079 |
0: SSLERR "SSL accept"
|
|
|
1080 |
1:
|
|
|
1081 |
LOG 2, "accepted"
|
|
|
1082 |
EPILOG
|
|
|
1083 |
#-----------------------------------------------
|
|
|
1084 |
# R E A D F R O M C O M M S O C K E T
|
|
|
1085 |
#-----------------------------------------------
|
|
|
1086 |
ARGS
|
|
|
1087 |
DS sci # SocketInfo rank
|
|
|
1088 |
# returns length read
|
|
|
1089 |
PROLOC
|
|
|
1090 |
DL thisP # -->this Node
|
|
|
1091 |
DL deP # -->Debug inst
|
|
|
1092 |
DL shP # -->shared mem
|
|
|
1093 |
DL currSockP # -->curr SocketInfo
|
|
|
1094 |
DL n # len read
|
|
|
1095 |
DL rest # len to be read
|
|
|
1096 |
DL buf # read dest
|
|
|
1097 |
EPILOC
|
|
|
1098 |
#-----------------------------------------------
|
|
|
1099 |
.global N.read
|
|
|
1100 |
N.read:
|
|
|
1101 |
PROLOG
|
|
|
1102 |
mov b, thisP(bp) # save -->this Node
|
|
|
1103 |
lea N.debug(b), a
|
|
|
1104 |
mov a, deP(bp) # save local -->Debug
|
|
|
1105 |
|
|
|
1106 |
mov C.csP, a # -->CS
|
|
|
1107 |
mov C.shP(a), a # -->shared mem
|
|
|
1108 |
mov a, shP(bp) # save -->shared mem
|
|
|
1109 |
push N.dataP(b)
|
|
|
1110 |
call Da.getDataLen
|
|
|
1111 |
mov a, rest(bp) # init len to be read
|
|
|
1112 |
call Da.getContP
|
|
|
1113 |
mov a, buf(bp) # init read dest
|
|
|
1114 |
mov N.srvSideP(b), c # -->server side SocketInfo array
|
|
|
1115 |
mov $SocketInfoL, a
|
|
|
1116 |
mull sci(bp) # curr SocketInfo offset
|
|
|
1117 |
lea (c, a), c # -->curr SocketInfo
|
|
|
1118 |
mov c, currSockP(bp) # save -->curr SocketInfo
|
|
|
1119 |
|
|
|
1120 |
push So.sc(c) # comm socket
|
|
|
1121 |
push rest(bp) # len to be read
|
|
|
1122 |
LOG 5, "ready to read len=%d from sc=%d..."
|
|
|
1123 |
# iterate on reading until whole length is read
|
|
|
1124 |
N.readIterate:
|
|
|
1125 |
cmp $0, rest(bp) # something to be read ?
|
|
|
1126 |
jng N.readAcc # no, end reading
|
|
|
1127 |
push rest(bp) # len to be read
|
|
|
1128 |
push buf(bp) # read dest
|
|
|
1129 |
mov currSockP(bp), c # curr SocketInfo
|
|
|
1130 |
cmp $1, N.ssl(b) # SSL ?
|
|
|
1131 |
jne 0f # no
|
|
|
1132 |
# read w/ SSL
|
|
|
1133 |
push So.sslP(c) # -->SSL struct
|
|
|
1134 |
SYS SSL_read
|
|
|
1135 |
jmp 1f
|
|
|
1136 |
# read w/o SSL
|
|
|
1137 |
0:
|
|
|
1138 |
push So.sc(c) # socket #
|
|
|
1139 |
SYS read
|
|
|
1140 |
# adjust read controls
|
|
|
1141 |
1:
|
|
|
1142 |
jz N.readEof # EOF read
|
|
|
1143 |
add a, buf(bp) # adjust -->read dest
|
|
|
1144 |
sub a, rest(bp) # decrement rest to read
|
|
|
1145 |
cmp $0, rest(bp) # everything read ?
|
|
|
1146 |
jng 0f
|
|
|
1147 |
push a
|
|
|
1148 |
LOG 5, "partly read %d bytes"
|
|
|
1149 |
0: jmp N.readIterate
|
|
|
1150 |
# account data just read
|
|
|
1151 |
N.readAcc:
|
|
|
1152 |
mov shP(bp), a # -->shared mem
|
|
|
1153 |
lea S.counter_sem(a), a # overall msg counter semaphore
|
|
|
1154 |
push a
|
|
|
1155 |
SYS sem_wait # get semaphore
|
|
|
1156 |
mov shP(bp), a
|
|
|
1157 |
incl S.msgs(a) # incr msgs counter
|
|
|
1158 |
lea S.counter_sem(a), a # overall msg counter semaphore
|
|
|
1159 |
push a
|
|
|
1160 |
SYS sem_post # post semaphore
|
|
|
1161 |
|
|
|
1162 |
lea -4(sp), sp # adjust stacker
|
|
|
1163 |
push N.dataP(b) # -->Data
|
|
|
1164 |
call Da.getPort
|
|
|
1165 |
mov a, 4(sp) # remote listen port
|
|
|
1166 |
call Da.getDataLen
|
|
|
1167 |
mov a, (sp) # data length
|
|
|
1168 |
LOG 5, "%d read from node %u"
|
|
|
1169 |
mov (sp), a # return len read
|
|
|
1170 |
jmp N.readRet
|
|
|
1171 |
# EOF read, finish
|
|
|
1172 |
N.readEof:
|
|
|
1173 |
LOG 4, "EOF read"
|
|
|
1174 |
N.readRet:
|
|
|
1175 |
EPILOG_R
|
|
|
1176 |
#-----------------------------------------------
|
|
|
1177 |
# W R I T E T O C O M M S O C K E T
|
|
|
1178 |
#-----------------------------------------------
|
|
|
1179 |
ARGS
|
|
|
1180 |
DS sci # SocketInfo rank
|
|
|
1181 |
# returns length written
|
|
|
1182 |
PROLOC
|
|
|
1183 |
DL thisP # -->this Node
|
|
|
1184 |
DL deP # -->Debug inst
|
|
|
1185 |
DL currSockP # -->curr SocketInfo
|
|
|
1186 |
DL n # len written
|
|
|
1187 |
DL rest # len to be written
|
|
|
1188 |
DL buf # write orig
|
|
|
1189 |
EPILOC
|
|
|
1190 |
#-----------------------------------------------
|
|
|
1191 |
.global N.write
|
|
|
1192 |
N.write:
|
|
|
1193 |
PROLOG
|
|
|
1194 |
mov b, thisP(bp) # save -->this Node
|
|
|
1195 |
lea N.debug(b), a
|
|
|
1196 |
mov a, deP(bp) # save local -->Debug
|
|
|
1197 |
# init control values
|
|
|
1198 |
mov C.csP, a # -->CS
|
|
|
1199 |
mov C.shP(a), a # -->shared mem
|
|
|
1200 |
mov a, shP(bp) # save -->shared mem
|
|
|
1201 |
push N.dataP(b) # -->Data
|
|
|
1202 |
call Da.getDataLen
|
|
|
1203 |
mov a, rest(bp) # init len to be written
|
|
|
1204 |
call Da.getContP
|
|
|
1205 |
mov a, buf(bp) # init write orig
|
|
|
1206 |
mov N.cliSideP(b), c # -->SocketInfo array
|
|
|
1207 |
mov $SocketInfoL, a
|
|
|
1208 |
mull sci(bp) # curr SocketInfo offset
|
|
|
1209 |
lea (c, a), c # -->curr SocketInfo
|
|
|
1210 |
mov c, currSockP(bp) # save -->curr SocketInfo
|
|
|
1211 |
|
|
|
1212 |
push So.sc(c) # comm socket
|
|
|
1213 |
push rest(bp) # len to be written
|
|
|
1214 |
LOG 5, "ready to write len=%d to sc=%d..."
|
|
|
1215 |
# iterate on writing until whole length is written
|
|
|
1216 |
N.writeIterate:
|
|
|
1217 |
cmp $0, rest(bp) # something to be written ?
|
|
|
1218 |
jng N.writeEnd # no, end writing
|
|
|
1219 |
push rest(bp) # len to be written
|
|
|
1220 |
push buf(bp) # write orig
|
|
|
1221 |
cmp $1, N.ssl(b) # SSL ?
|
|
|
1222 |
jne 0f # no
|
|
|
1223 |
# SSL
|
|
|
1224 |
pushl So.sslP(c) # -->SSL struct
|
|
|
1225 |
SYS SSL_write
|
|
|
1226 |
jmp 1f
|
|
|
1227 |
# no SSL
|
|
|
1228 |
0:
|
|
|
1229 |
pushl So.sc(c) # socket
|
|
|
1230 |
SYS write
|
|
|
1231 |
# adjust write controls
|
|
|
1232 |
1:
|
|
|
1233 |
mov a, n(bp) # save len written
|
|
|
1234 |
add a, buf(bp) # adjust write orig
|
|
|
1235 |
sub a, rest(bp) # decrement rest to write
|
|
|
1236 |
cmp $0, rest(bp) # everything written ?
|
|
|
1237 |
jng 0f
|
|
|
1238 |
push a
|
|
|
1239 |
LOG 5, "partly written %d bytes"
|
|
|
1240 |
0: jmp N.writeIterate
|
|
|
1241 |
# return datalen
|
|
|
1242 |
N.writeEnd:
|
|
|
1243 |
mov N.dataP(b), a
|
|
|
1244 |
mov Da.datalen(a), a
|
|
|
1245 |
push a
|
|
|
1246 |
LOG 5, "%d written", 1
|
|
|
1247 |
EPILOG_R
|
|
|
1248 |
#-----------------------------------------------
|
|
|
1249 |
# G E T D A T A F R O M C O M M S O C K E T
|
|
|
1250 |
#-----------------------------------------------
|
|
|
1251 |
ARGS
|
|
|
1252 |
DS sci # SocketInfo rank
|
|
|
1253 |
# returns boolean: 0 - EOF read, 1 - data read
|
|
|
1254 |
PROLOC
|
|
|
1255 |
DL thisP # -->this Node
|
|
|
1256 |
DL deP
|
|
|
1257 |
EPILOC
|
|
|
1258 |
#-----------------------------------------------
|
|
|
1259 |
.global N.get
|
|
|
1260 |
N.get:
|
|
|
1261 |
PROLOG
|
|
|
1262 |
mov b, thisP(bp) # save -->this Node
|
|
|
1263 |
lea N.debug(b), a
|
|
|
1264 |
mov a, deP(bp) # save local -->Debug
|
|
|
1265 |
push sci(bp) # SocketInfo rank
|
|
|
1266 |
LOG 5, "get data from socket, rank=%u"
|
|
|
1267 |
call N.read
|
|
|
1268 |
test a, a
|
|
|
1269 |
jz 0f
|
|
|
1270 |
mov $1, a
|
|
|
1271 |
0: EPILOG_R
|
|
|
1272 |
#-----------------------------------------------
|
|
|
1273 |
# P U T D A T A T O C O M M S O C K E T
|
|
|
1274 |
#-----------------------------------------------
|
|
|
1275 |
ARGS
|
|
|
1276 |
DS sci # SocketInfo rank
|
|
|
1277 |
# returns boolean: 0 - nothing written, 1 - data written
|
|
|
1278 |
PROLOC
|
|
|
1279 |
DL thisP # -->this Node
|
|
|
1280 |
DL deP
|
|
|
1281 |
EPILOC
|
|
|
1282 |
#-----------------------------------------------
|
|
|
1283 |
.global N.put
|
|
|
1284 |
N.put:
|
|
|
1285 |
PROLOG
|
|
|
1286 |
mov b, thisP(bp) # save -->this Node
|
|
|
1287 |
lea N.debug(b), a
|
|
|
1288 |
mov a, deP(bp) # save local -->Debug
|
|
|
1289 |
LOG 5, "put data to socket"
|
|
|
1290 |
|
|
|
1291 |
mov N.dataP(b), d # -->Data
|
|
|
1292 |
mov Da.contP(d), a # -->container
|
|
|
1293 |
lea Co.hdr(a), a # -->header
|
|
|
1294 |
mov N.locPort(b), c
|
|
|
1295 |
mov c, H.lport(a) # listen port to header
|
|
|
1296 |
|
|
|
1297 |
pushl sci(bp) # SocketInfo rank
|
|
|
1298 |
call N.write
|
|
|
1299 |
test a, a
|
|
|
1300 |
jz 0f
|
|
|
1301 |
mov $1, a
|
|
|
1302 |
0: EPILOG_R
|
|
|
1303 |
#-----------------------------------------------
|
|
|
1304 |
# C L O S E C O N N E C T I O N S O C K E T
|
|
|
1305 |
#-----------------------------------------------
|
|
|
1306 |
ARGS
|
|
|
1307 |
DS sci # SocketInfo rank
|
|
|
1308 |
DS server # indicate server or client
|
|
|
1309 |
DS deP # -->Debug inst
|
|
|
1310 |
# returns:# nothing
|
|
|
1311 |
PROLOC
|
|
|
1312 |
DL thisP # -->this Node
|
|
|
1313 |
DL currSockP # -->curr SocketInfo
|
|
|
1314 |
DL tagP
|
|
|
1315 |
DL e
|
|
|
1316 |
EPILOC
|
|
|
1317 |
N.srvSideTag: .asciz "server side"
|
|
|
1318 |
N.cliSideTag: .asciz "client side"
|
|
|
1319 |
#-----------------------------------------------
|
|
|
1320 |
.global N.closeSocket
|
|
|
1321 |
N.closeSocket:
|
|
|
1322 |
PROLOG
|
|
|
1323 |
mov b, thisP(bp) # save -->this Node
|
|
|
1324 |
mov N.srvSideP(b), c # -->SocketInfo array
|
|
|
1325 |
movl $N.srvSideTag, tagP(bp)
|
|
|
1326 |
cmp $1, server(bp) # server side ?
|
|
|
1327 |
je 0f
|
|
|
1328 |
mov N.cliSideP(b), c # client side
|
|
|
1329 |
movl $N.cliSideTag, tagP(bp)
|
|
|
1330 |
0: mov $SocketInfoL, a
|
|
|
1331 |
mull sci(bp) # curr SocketInfo offset
|
|
|
1332 |
lea (c, a), c
|
|
|
1333 |
mov c, currSockP(bp) # save -->curr SocketInfo
|
|
|
1334 |
push So.sc(c) # socket to close
|
|
|
1335 |
push tagP(bp)
|
|
|
1336 |
LOG 5, "closing %s sc=%u...", 2
|
|
|
1337 |
|
|
|
1338 |
cmp $0, N.ssl(b) # SSL ?
|
|
|
1339 |
je 2f # no
|
|
|
1340 |
# SSL shutdown
|
|
|
1341 |
pushl So.sslP(c) # -->SSL structure
|
|
|
1342 |
call SSL_shutdown
|
|
|
1343 |
cmp $0, a
|
|
|
1344 |
jns 0f # no err
|
|
|
1345 |
SSLERR "SSL shutdown (1)"
|
|
|
1346 |
0: jnz 2f # SSL shutdown finished
|
|
|
1347 |
LOG 5, "SSL shutdown rc=0, retry"
|
|
|
1348 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
1349 |
pushl So.sslP(c) # -->SSL structure
|
|
|
1350 |
call SSL_shutdown
|
|
|
1351 |
cmp $0, a
|
|
|
1352 |
jg 2f # SSL shutdown finished
|
|
|
1353 |
push a # SSL err
|
|
|
1354 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
1355 |
pushl So.sslP(c) # -->SSL structure
|
|
|
1356 |
call SSL_get_error
|
|
|
1357 |
cmp $5, a # SSL_ERROR_SYSCALL ?
|
|
|
1358 |
jne 1f # no, other SSL err
|
|
|
1359 |
# syscall err
|
|
|
1360 |
call ERR_get_error
|
|
|
1361 |
test a, a # SSL err ?
|
|
|
1362 |
jnz 2f # yes, don't care
|
|
|
1363 |
call __errno_location # sys err ?
|
|
|
1364 |
test a, a
|
|
|
1365 |
jz 2f # no
|
|
|
1366 |
SYSERR "SSL shutdown (2)"
|
|
|
1367 |
# other SSL err, print SSL err queue
|
|
|
1368 |
1: SSLERR "SSL shutdown (2)"
|
|
|
1369 |
# close socket
|
|
|
1370 |
2: mov currSockP(bp), c # -->curr SocketInfo
|
|
|
1371 |
pushl So.sc(c) # socket to close
|
|
|
1372 |
# call close
|
|
|
1373 |
# test a, a
|
|
|
1374 |
# jz 0f
|
|
|
1375 |
# SYSERR "close"
|
|
|
1376 |
#0:
|
|
|
1377 |
SYS close
|
|
|
1378 |
push tagP(bp)
|
|
|
1379 |
LOG 4, "%s sc=%u closed", 2
|
|
|
1380 |
mov currSockP(bp), c # -->curr SocketInfo
|
|
|
1381 |
movl $-1, So.sc(c) # indicate closed socket
|
|
|
1382 |
EPILOG
|
|
|
1383 |
#-----------------------------------------------
|
|
|
1384 |
# C R E A T E T H R E A D T O C L O S E C L I E N T S I D E S
|
|
|
1385 |
#-----------------------------------------------
|
|
|
1386 |
ARGS
|
|
|
1387 |
PROLOC
|
|
|
1388 |
DL thisP # -->this Node
|
|
|
1389 |
DL deP # -->Debug inst
|
|
|
1390 |
DL pt # pthread_t (int)
|
|
|
1391 |
EPILOC
|
|
|
1392 |
#-----------------------------------------------
|
|
|
1393 |
N.closeClients:
|
|
|
1394 |
PROLOG
|
|
|
1395 |
mov b, thisP(bp) # save -->this Node
|
|
|
1396 |
lea N.debug(b), a
|
|
|
1397 |
mov a, deP(bp) # save local -->Debug
|
|
|
1398 |
cmp $1, N.closing(b)
|
|
|
1399 |
je 0f # already closing, nothing to do
|
|
|
1400 |
LOG 5, "spawning thread to close client side"
|
|
|
1401 |
push b # -->this (param for thread)
|
|
|
1402 |
pushl $N.closeCliThread # -->thread func
|
|
|
1403 |
pushl $0
|
|
|
1404 |
lea N.ptid(b), a # -->thread ID
|
|
|
1405 |
push a
|
|
|
1406 |
call pthread_create
|
|
|
1407 |
test a, a
|
|
|
1408 |
jz 1f
|
|
|
1409 |
SYSERR "create thread"
|
|
|
1410 |
1: mov thisP(bp), b # -->this Node
|
|
|
1411 |
movl $1, N.closing(b) # indicate "closing"
|
|
|
1412 |
push N.ptid(b)
|
|
|
1413 |
LOG 5, "closing thread (%u) spawned"
|
|
|
1414 |
0: EPILOG
|
|
|
1415 |
#-----------------------------------------------
|
|
|
1416 |
# C L O S E C L I E N T S I D E S
|
|
|
1417 |
#-----------------------------------------------
|
|
|
1418 |
ARGS
|
|
|
1419 |
DS thisP
|
|
|
1420 |
PROLOC
|
|
|
1421 |
DL deP # -->Debug inst
|
|
|
1422 |
DL debug, DebugL
|
|
|
1423 |
EPILOC
|
|
|
1424 |
#-----------------------------------------------
|
|
|
1425 |
N.closeCliThread:
|
|
|
1426 |
PROLOG
|
|
|
1427 |
mov thisP(bp), b # -->this Node
|
|
|
1428 |
lea debug(bp), a
|
|
|
1429 |
mov a, deP(bp) # save deP
|
|
|
1430 |
lea N.debug(b), a
|
|
|
1431 |
lea D.id(a), a # -->caller debug id
|
|
|
1432 |
push a
|
|
|
1433 |
DEBID "%s CLOSE clients", 1
|
|
|
1434 |
LOG 5, "start..."
|
|
|
1435 |
mov $0, c # offet in socket info array
|
|
|
1436 |
mov $0, d # socket info rank
|
|
|
1437 |
mov N.cliSideP(b), a # -->client socket info array
|
|
|
1438 |
0: # iterate on opened sockets
|
|
|
1439 |
cmp $-1, So.sc(a, c) # sc allocated ?
|
|
|
1440 |
je 1f # no, iterate
|
|
|
1441 |
push So.sc(a, c) # socket#
|
|
|
1442 |
LOG 4, "sc=%u"
|
|
|
1443 |
push deP(bp)
|
|
|
1444 |
pushl $0 # indicate "client"
|
|
|
1445 |
push d # socket info rank
|
|
|
1446 |
call N.closeSocket # close socket
|
|
|
1447 |
1: inc d
|
|
|
1448 |
cmp N.nodes(b), d # rank < nodes ?
|
|
|
1449 |
je 0f # no, end
|
|
|
1450 |
lea SocketInfoL(c), c # incr offset
|
|
|
1451 |
jmp 0b # iterate
|
|
|
1452 |
0: LOG 4, "finished, exiting thread"
|
|
|
1453 |
pushl $0
|
|
|
1454 |
call pthread_exit
|
|
|
1455 |
EPILOG
|
|
|
1456 |
#-----------------------------------------------
|
|
|
1457 |
# S Y N C H R O N I Z E A L L N O D E S
|
|
|
1458 |
#-----------------------------------------------
|
|
|
1459 |
ARGS
|
|
|
1460 |
PROLOC
|
|
|
1461 |
DL thisP
|
|
|
1462 |
DL deP
|
|
|
1463 |
DL shP
|
|
|
1464 |
DL tosignal
|
|
|
1465 |
DL sigmask, 128
|
|
|
1466 |
DL sigact, SigActionL
|
|
|
1467 |
EPILOC
|
|
|
1468 |
N.sync:
|
|
|
1469 |
PROLOG
|
|
|
1470 |
mov b, thisP(bp) # save -->this Node
|
|
|
1471 |
lea N.debug(b), a
|
|
|
1472 |
mov a, deP(bp) # save -->Debug locally for LOG macro
|
|
|
1473 |
|
|
|
1474 |
movl $0, tosignal(bp)
|
|
|
1475 |
mov C.csP, c # -->CS
|
|
|
1476 |
mov C.shP(c), a # -->shared mem
|
|
|
1477 |
push S.act(a)
|
|
|
1478 |
mov a, shP(bp)
|
|
|
1479 |
push N.pid(b)
|
|
|
1480 |
LOG 5, "%u synchronizing: active=%u"
|
|
|
1481 |
# set signal handler block
|
|
|
1482 |
lea sigact(bp), a
|
|
|
1483 |
movl $N.sighandle, sa_handler(a)
|
|
|
1484 |
movl $0, sa_flags(a)
|
|
|
1485 |
lea sa_mask(a), a # set handler mask
|
|
|
1486 |
push a
|
|
|
1487 |
SYS sigfillset
|
|
|
1488 |
jmp 0f
|
|
|
1489 |
N.sighandle:
|
|
|
1490 |
ret
|
|
|
1491 |
0:
|
|
|
1492 |
# activate signal handler
|
|
|
1493 |
lea sigmask(bp), a
|
|
|
1494 |
push a
|
|
|
1495 |
SYS sigemptyset
|
|
|
1496 |
push $SIGUSR2
|
|
|
1497 |
lea sigmask(bp), a
|
|
|
1498 |
push a
|
|
|
1499 |
SYS sigaddset
|
|
|
1500 |
push $0
|
|
|
1501 |
lea sigmask(bp), a
|
|
|
1502 |
push a
|
|
|
1503 |
push $SIG_UNBLOCK
|
|
|
1504 |
SYS sigprocmask
|
|
|
1505 |
push $0
|
|
|
1506 |
lea sigact(bp), a
|
|
|
1507 |
push a
|
|
|
1508 |
push $SIGUSR2
|
|
|
1509 |
SYS sigaction
|
|
|
1510 |
# update nodes counter
|
|
|
1511 |
mov shP(bp), a
|
|
|
1512 |
lea S.counter_sem(a), a
|
|
|
1513 |
push a
|
|
|
1514 |
SYS sem_wait # get semaphore
|
|
|
1515 |
mov shP(bp), a
|
|
|
1516 |
decl S.act(a) # decrement nodes counter
|
|
|
1517 |
setz tosignal(bp)
|
|
|
1518 |
mov shP(bp), a
|
|
|
1519 |
lea S.counter_sem(a), a
|
|
|
1520 |
push a
|
|
|
1521 |
SYS sem_post # post semaphore
|
|
|
1522 |
testl $1, tosignal(bp) # all finished?
|
|
|
1523 |
jz N.sigwait
|
|
|
1524 |
# signal all tasks
|
|
|
1525 |
push N.pid(b)
|
|
|
1526 |
LOG 5, "%u signaling USR2"
|
|
|
1527 |
push $SIGUSR2
|
|
|
1528 |
push $0
|
|
|
1529 |
SYS kill
|
|
|
1530 |
jmp N.woken
|
|
|
1531 |
# wait for signal
|
|
|
1532 |
N.sigwait:
|
|
|
1533 |
# call pause
|
|
|
1534 |
push $5
|
|
|
1535 |
call sleep
|
|
|
1536 |
N.woken:
|
|
|
1537 |
mov thisP(bp), b # -->this Node
|
|
|
1538 |
push N.pid(b)
|
|
|
1539 |
LOG 5, "%u woken up"
|
|
|
1540 |
EPILOG
|
|
|
1541 |
#-----------------------------------------------
|
|
|
1542 |
# F O R M A T A N D P R I N T S S L E R R O R
|
|
|
1543 |
#-----------------------------------------------
|
|
|
1544 |
# args
|
|
|
1545 |
ac = 8
|
|
|
1546 |
DS deP # -->Debug
|
|
|
1547 |
DS msgP # -->accompanying msg str
|
|
|
1548 |
# returns: nothing
|
|
|
1549 |
PROLOC
|
|
|
1550 |
DL str, 256 # generated string buf
|
|
|
1551 |
EPILOC
|
|
|
1552 |
#-----------------------------------------------
|
|
|
1553 |
.global N.sslErr
|
|
|
1554 |
N.sslErr:
|
|
|
1555 |
enter $locL, $0
|
|
|
1556 |
0:
|
|
|
1557 |
call ERR_get_error
|
|
|
1558 |
push a
|
|
|
1559 |
LOG 5, "ssl err, e=%lu", 1
|
|
|
1560 |
test a, a # end of msg queue ?
|
|
|
1561 |
jz 0f # yes
|
|
|
1562 |
lea str(bp), d
|
|
|
1563 |
push d # -->err msg str buf
|
|
|
1564 |
push a # err
|
|
|
1565 |
call ERR_error_string
|
|
|
1566 |
push a # -->err msg str
|
|
|
1567 |
pushl msgP(bp) # -->accompanying msg str
|
|
|
1568 |
LOG 0, "%s: %s", 2
|
|
|
1569 |
jmp 0b # iterate on SSL err msg queue
|
|
|
1570 |
0:
|
|
|
1571 |
pushl $1
|
|
|
1572 |
call exit # ABEND
|
|
|
1573 |
#-----------------------------------------------
|
|
|
1574 |
# G E T A S S I G N E D I P A D D R
|
|
|
1575 |
#-----------------------------------------------
|
|
|
1576 |
# puts assigned IP address:port in string
|
|
|
1577 |
ARGS
|
|
|
1578 |
DS sP # -->output string
|
|
|
1579 |
DS saP # -->sockaddr
|
|
|
1580 |
DS deP # -->Debug
|
|
|
1581 |
# returns: nothing
|
|
|
1582 |
PROLOC
|
|
|
1583 |
EPILOC
|
|
|
1584 |
#-----------------------------------------------
|
|
|
1585 |
gai: PROLOG
|
|
|
1586 |
|
|
|
1587 |
mov saP(bp), b # -->sockaddr
|
|
|
1588 |
xor a, a
|
|
|
1589 |
mov sa_data(b), %ax # port # in big endian order
|
|
|
1590 |
push a
|
|
|
1591 |
call ntohs
|
|
|
1592 |
mov a, d
|
|
|
1593 |
|
|
|
1594 |
mov saP(bp), b # -->sockaddr
|
|
|
1595 |
pushl sa_data+2(b) # IP addr in big endian order
|
|
|
1596 |
call ntohl
|
|
|
1597 |
|
|
|
1598 |
push d # port # as int
|
|
|
1599 |
|
|
|
1600 |
mov $4, c # iterate on 4 bytes of IP addr
|
|
|
1601 |
0: mov a, d
|
|
|
1602 |
and $0xff, d
|
|
|
1603 |
push d # part of IP addr
|
|
|
1604 |
shr $8, a
|
|
|
1605 |
dec c
|
|
|
1606 |
jnz 0b # iterate
|
|
|
1607 |
|
|
|
1608 |
push $0f
|
|
|
1609 |
pushl sP(bp) # -->output buf
|
|
|
1610 |
call sprintf
|
|
|
1611 |
jmp 1f
|
|
|
1612 |
0: .ascii "%u.%u.%u.%u:%d\0"
|
|
|
1613 |
1:
|
|
|
1614 |
EPILOG
|
|
|
1615 |
#-----------------------------------------------
|
|
|
1616 |
.end
|