|
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 |