2 * Connection oriented routing user space utils
3 * Copyright (C) 2009-2011
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #include <linux/types.h>
32 #define likely(x) __builtin_expect((x), 1)
33 #define unlikely(x) __builtin_expect((x), 0)
36 #define CD_CONNECT_NB 1
37 #define CD_CONNECT_PORT 2
38 #define CD_LIST_NEIGH 3
39 #define CD_SET_FORWARD_TIMEOUT 4
40 #define CD_SET_BACKWARD_TIMEOUT 5
44 #define CDR_EXECFAILED 2
45 #define CDR_EXECFAILED_UNKNOWN_COMMAND 1
46 #define CDR_EXECFAILED_PERMISSION_DENIED 2
47 #define CDR_EXECFAILED_TEMPORARILY_OUT_OF_RESSOURCES 3
48 #define CDR_EXECFAILED_CMD_TOO_SHORT 4
49 #define CDR_EXECFAILED_CMD_TOO_LONG 5
50 #define CDR_EXECFAILED_TARGETADDR_DOESNTEXIST 6
51 #define CDR_EXECFAILED_PORTCLOSED 7
52 #define CDR_EXECFAILED_LISTENERQUEUE_FULL 8
53 #define CDR_EXECFAILED_ILLEGAL_COMMAND 9
57 #define LIST_NEIGH_FIELD_ADDR 1
58 #define LIST_NEIGH_FIELD_LATENCY 2
62 #define CRD_KTU_CONNECT 1
66 * CRD_KTU_CONNECT[4] length[4] flags[8] addrlen[4] addr[addrlen]
71 #define CRD_UTK_CONNECTERROR 2
73 * CRD_KTU_CONNECT[4] length[4] cookie[8] error[4]
77 static int bzero_nr_iffinished(
78 struct libcor_nonblock_resumeinfo
*nr
, int rc
)
80 if (rc
!= RC_WOULDBLOCK
) {
81 bzero(nr
, sizeof(struct libcor_nonblock_resumeinfo
));
86 static int send_fully(int fd
, char *buf
, __u32 len
)
89 int sent
= send(fd
, buf
, len
, 0);
92 printf("non-blocking write not supported");
101 return RC_CONNBROKEN
;
111 static int read_fully(int fd
, struct libcor_nonblock_resumeinfo
*nr
,
112 char *buf
, __u32 len
, __u32
*maxread
)
116 if (unlikely(nr
->type
!= RESUME_TYPE_READ
)) {
119 return RC_CONNBROKEN
;
122 if (unlikely(nr
->data
.read
.read_fully
.state
!= 0 && (
123 nr
->data
.read
.read_fully
.fd
!= fd
||
124 nr
->data
.read
.read_fully
.buf
!= buf
||
125 nr
->data
.read
.read_fully
.len
!= len
||
126 nr
->data
.read
.read_fully
.maxread
!= maxread
))) {
129 return RC_CONNBROKEN
;
132 if (nr
->data
.read
.read_fully
.state
== 1) {
134 } else if (unlikely(nr
->data
.read
.read_fully
.state
!= 0)) {
137 return RC_CONNBROKEN
;
140 nr
->data
.read
.read_fully
.fd
= fd
;
141 nr
->data
.read
.read_fully
.buf
= buf
;
142 nr
->data
.read
.read_fully
.len
= len
;
143 nr
->data
.read
.read_fully
.maxread
= maxread
;
144 nr
->data
.read
.read_fully
.totalread
= 0;
146 nr
->data
.read
.read_fully
.state
= 1;
150 if (len
> (*maxread
)) {
151 printf("error in read_fully: maxread reached/n");
158 while (len
> nr
->data
.read
.read_fully
.totalread
) {
159 int rcvd
= recv(fd
, buf
+ nr
->data
.read
.read_fully
.totalread
,
160 len
- nr
->data
.read
.read_fully
.totalread
, 0);
164 printf("non-blocking read not supported");
178 /*printf("rcvd: %d:", rcvd);
179 for(u=0;u<rcvd;u++) {
180 printf(" %d, ", (__s32) ((__u8) buf[totalread+u]));
184 nr
->data
.read
.read_fully
.totalread
+= (__u32
) rcvd
;
188 if (rc
!= RC_WOULDBLOCK
) {
189 bzero(&(nr
->data
.read
.read_fully
),
190 sizeof(nr
->data
.read
.read_fully
));
196 static int read_discard(int fd
, struct libcor_nonblock_resumeinfo
*nr
,
202 if (unlikely(nr
->type
!= RESUME_TYPE_READ
)) {
205 return RC_CONNBROKEN
;
208 if (unlikely(nr
->data
.read
.read_discard
.state
!= 0 && (
209 nr
->data
.read
.read_discard
.fd
!= fd
||
210 nr
->data
.read
.read_discard
.len
!= len
))) {
213 return RC_CONNBROKEN
;
216 if (nr
->data
.read
.read_discard
.state
== 1) {
218 } else if (unlikely(nr
->data
.read
.read_discard
.state
!= 0)) {
221 return RC_CONNBROKEN
;
224 nr
->data
.read
.read_discard
.fd
= fd
;
225 nr
->data
.read
.read_discard
.len
= len
;
226 nr
->data
.read
.read_discard
.discarded
= 0;
229 nr
->data
.read
.read_discard
.state
= 1;
235 __u32 rcvlen
= len
- nr
->data
.read
.read_discard
.discarded
;
239 rcvd
= recv(fd
, buf
, rcvlen
, 0);
255 nr
->data
.read
.read_discard
.discarded
-= rcvd
;
259 if (rc
!= RC_WOULDBLOCK
) {
260 bzero(&(nr
->data
.read
.read_discard
),
261 sizeof(nr
->data
.read
.read_discard
));
267 static int encode_len(char *buf
, int buflen
, __u32 len
)
269 if (unlikely(buf
== 0))
272 if (unlikely(buflen
< 4))
281 buf
[0] = (__u8
) ((len
- 128) /256 + 128);
282 buf
[1] = (__u8
) ((len
- 128) & 255);
286 if (len
< 1073741951) {
287 __u32 len_be
= htonl(len
- 16511);
288 char *len_p
= (char *) &len_be
;
290 buf
[0] = len_p
[0] + 192;
300 static int decode_len(char *buf
, int buflen
, __u32
*len
)
302 if (unlikely(buflen
< 1))
305 if ((__u8
) buf
[0] <= 127) {
306 *len
= (__u8
) buf
[0];
313 if ((__u8
) buf
[0] <= 191) {
314 *len
= 128 + ((__u32
) ((__u8
) buf
[0]) - 128) * 256 +
322 ((char *) len
)[0] = buf
[0] - 192;
323 ((char *) len
)[1] = buf
[1];
324 ((char *) len
)[2] = buf
[2];
325 ((char *) len
)[3] = buf
[3];
327 *len
= ntohl(*len
) + 16511;
332 static int read_len(int fd
, struct libcor_nonblock_resumeinfo
*nr
,
333 __u32
*len
, __u32
*maxread
)
335 int rc
= RC_CONNBROKEN
;
337 if (unlikely(nr
->type
!= RESUME_TYPE_READ
)) {
340 return RC_CONNBROKEN
;
343 if (unlikely(nr
->data
.read
.read_len
.state
!= 0 && (
344 nr
->data
.read
.read_len
.fd
!= fd
||
345 nr
->data
.read
.read_len
.len
!= len
||
346 nr
->data
.read
.read_len
.maxread
!= maxread
))) {
349 return RC_CONNBROKEN
;
352 if (sizeof(nr
->data
.read
.read_len
.buf
) != 4) {
355 return RC_CONNBROKEN
;
358 if (nr
->data
.read
.read_len
.state
== 1) {
360 } else if (unlikely(nr
->data
.read
.read_len
.state
!= 0)) {
363 return RC_CONNBROKEN
;
366 nr
->data
.read
.read_len
.fd
= fd
;
367 nr
->data
.read
.read_len
.len
= len
;
368 nr
->data
.read
.read_len
.maxread
= maxread
;
369 bzero(&(nr
->data
.read
.read_len
.buf
[0]), 4);
370 nr
->data
.read
.read_len
.read
= 0;
374 nr
->data
.read
.read_len
.state
= 1;
376 if (nr
->data
.read
.read_len
.read
>= 4) {
377 printf("error in readlen: read to high\n");
381 rc
= read_fully(fd
, nr
, &(nr
->data
.read
.read_len
.buf
[0]) +
382 nr
->data
.read
.read_len
.read
, 1, maxread
);
386 nr
->data
.read
.read_len
.read
++;
388 rc
= decode_len(&(nr
->data
.read
.read_len
.buf
[0]),
389 nr
->data
.read
.read_len
.read
, len
);
391 if (unlikely(rc
< nr
->data
.read
.read_len
.read
)) {
392 printf("error in readlen: decode_len has not "
393 "consumed the whole buffer\n");
407 if (rc
!= RC_WOULDBLOCK
) {
408 bzero(&(nr
->data
.read
.read_len
),
409 sizeof(nr
->data
.read
.read_len
));
415 static int send_cmd_hdr(int fd
, __u16 cmd
, __u32 len
)
420 #warning todo commands are sent via multiple packets
424 cmdlenbuf
[0] = ((char *) &cmd
)[0];
425 cmdlenbuf
[1] = ((char *) &cmd
)[1];
427 rc
= encode_len(cmdlenbuf
+2, 4, len
);
430 return RC_CONNBROKEN
;
432 rc
= send_fully(fd
, cmdlenbuf
, 2 + rc
);
434 return RC_CONNBROKEN
;
439 static int send_cmd(int fd
, __u16 cmd
, char *buf
, __u32 len
)
441 int rc
= send_cmd_hdr(fd
, cmd
, len
);
444 return RC_CONNBROKEN
;
446 rc
= send_fully(fd
, buf
, len
);
448 return RC_CONNBROKEN
;
453 int read_resp_nonblock(int fd
, struct libcor_nonblock_resumeinfo
*nr
)
457 struct libcor_nonblock_resumeinfo_resp
*nr_resp
=
458 &(nr
->data
.read
.funcdata
.resp
);
460 if (nr
->type
== RESUME_TYPE_NONE
) {
461 bzero(nr
, sizeof(struct libcor_nonblock_resumeinfo
));
462 nr
->type
= RESUME_TYPE_READ
;
463 nr
->data
.read
.functype
= RESUME_READ_FUNC_RESP
;
465 } else if (unlikely(nr
->type
!= RESUME_TYPE_READ
||
466 nr
->data
.read
.functype
!= RESUME_READ_FUNC_RESP
)) {
469 return RC_CONNBROKEN
;
470 } else if (unlikely(nr_resp
->fd
!= fd
)) {
473 return RC_CONNBROKEN
;
475 __u8 state
= nr_resp
->state
;
479 } else if (state
== 2) {
481 } else if (state
== 3) {
483 } else if (unlikely(state
!= 0)) {
486 return RC_CONNBROKEN
;
490 nr_resp
->respcode
= 0;
491 rc
= read_fully(fd
, nr
, (char *) &(nr_resp
->respcode
), 1, 0);
494 return bzero_nr_iffinished(nr
, rc
);
496 if (nr_resp
->respcode
== CDR_EXECFAILED
) {
497 nr_resp
->reasoncode
= 0;
501 rc
= read_fully(fd
, nr
, (char *) &(nr_resp
->reasoncode
), 2, 0);
503 return bzero_nr_iffinished(nr
, rc
);
505 nr_resp
->reasoncode
= ntohs(nr_resp
->reasoncode
);
507 printf("execfailed: reasoncode = %d\n", (__s32
)
508 nr_resp
->reasoncode
);
512 rc
= read_len(fd
, nr
, &(nr_resp
->reasonlen
),
515 return bzero_nr_iffinished(nr
, rc
);
519 rc
= read_discard(fd
, nr
, nr_resp
->reasonlen
);
521 return bzero_nr_iffinished(nr
, rc
);
524 while (reasonlen > 0) {
525 __u32 nextread = reasonlen;
527 if (reasonlen > 4093)
529 reasonlen -= nextread;
530 int rc = read_fully(fd, buf, nextread, 0);
541 if (nr_resp
->respcode
== CDR_EXECOK
)
542 return bzero_nr_iffinished(nr
, RC_OK
);
544 return bzero_nr_iffinished(nr
, RC_CONNBROKEN
);
547 int read_resp(int fd
)
549 int rc
= RC_WOULDBLOCK
;
550 struct libcor_nonblock_resumeinfo nr
;
551 bzero(&nr
, sizeof(struct libcor_nonblock_resumeinfo
));
553 rc
= read_resp_nonblock(fd
, &nr
);
554 if (unlikely(rc
== RC_WOULDBLOCK
)) {
562 int send_connect_neigh(int fd
, __u32 addrlen
, char *addr
)
569 rc
= encode_len(buf
, 4, addrlen
);
570 if (unlikely(rc
<= 0))
571 return RC_CONNBROKEN
;
575 /* printf("send_connect_neigh %d %d %c%c\n", (int) addrtypelen,
576 * (int) addrlen, (char) addrtype[0],
577 * (char) addrtype[1]); */
579 rc
= send_cmd_hdr(fd
, CD_CONNECT_NB
, len
+ addrlen
);
581 return RC_CONNBROKEN
;
583 rc
= send_fully(fd
, buf
, len
);
585 return RC_CONNBROKEN
;
587 rc
= send_fully(fd
, addr
, addrlen
);
589 return RC_CONNBROKEN
;
594 int send_connect_port(int fd
, __u64 port
)
596 __u64 p
= htonll(port
);
597 return send_cmd(fd
, CD_CONNECT_PORT
, (char *) &p
, 8);
600 int send_list_neigh(int fd
, __u32 limit
, __u32 offset
)
606 rc
= encode_len(buf
, 4, limit
);
607 if (unlikely(rc
<= 0))
608 return RC_CONNBROKEN
;
612 rc
= encode_len(buf
+ len
, 4, offset
);
613 if (unlikely(rc
<= 0))
614 return RC_CONNBROKEN
;
618 return send_cmd(fd
, CD_LIST_NEIGH
, buf
, len
);
621 static int field_present(struct listneigh_field
*fields
, __u32 numfields
,
625 for(u
=0;u
<numfields
;u
++) {
626 if (fields
[u
].field
== field
)
632 int read_neigh_list_nonblock(int fd
, struct libcor_nonblock_resumeinfo
*nr
,
634 void (*init
)(void *ptr
, __u32 totalneighs
, __u32 responserows
),
635 void (*next_neigh
)(void *ptr
, __u32 addrlen
, char *addr
))
639 struct libcor_nonblock_resumeinfo_neighlist
*nr_nl
=
640 &(nr
->data
.read
.funcdata
.neighlist
);
642 if (nr
->type
== RESUME_TYPE_NONE
) {
643 bzero(nr
, sizeof(struct libcor_nonblock_resumeinfo
));
644 nr
->type
= RESUME_TYPE_READ
;
645 nr
->data
.read
.functype
= RESUME_READ_FUNC_NEIGHLIST
;
649 nr_nl
->next_neigh
= next_neigh
;
650 } else if (unlikely(nr
->type
!= RESUME_TYPE_READ
||
651 nr
->data
.read
.functype
!= RESUME_READ_FUNC_NEIGHLIST
)) {
654 return RC_CONNBROKEN
;
655 } else if (unlikely(nr_nl
->fd
!= fd
||
657 nr_nl
->init
!= init
||
658 nr_nl
->next_neigh
!= next_neigh
)) {
661 return RC_CONNBROKEN
;
663 __u8 state
= nr_nl
->state
;
666 } else if (state
== 2) {
668 } else if (state
== 3) {
670 } else if (state
== 4) {
672 } else if (state
== 5) {
674 } else if (state
== 6) {
676 } else if (state
== 7) {
678 } else if (state
== 8) {
680 } else if (state
== 9) {
682 } else if (state
==10) {
684 } else if (state
== 11) {
686 } else if (unlikely(state
!= 0)) {
689 return RC_CONNBROKEN
;
695 rc
= read_fully(fd
, nr
, (char *) &(nr_nl
->respcode
), 1, 0);
697 return bzero_nr_iffinished(nr
, rc
);
699 if (unlikely(nr_nl
->respcode
!= CDR_BINDATA
))
700 return bzero_nr_iffinished(nr
, RC_CONNBROKEN
);
704 rc
= read_len(fd
, nr
, &(nr_nl
->len
), 0);
706 return bzero_nr_iffinished(nr
, rc
);
710 rc
= read_len(fd
, nr
, &(nr_nl
->totalneighs
), &(nr_nl
->len
));
712 return bzero_nr_iffinished(nr
, rc
);
716 rc
= read_len(fd
, nr
, &(nr_nl
->response_rows
), &(nr_nl
->len
));
718 return bzero_nr_iffinished(nr
, rc
);
722 rc
= read_len(fd
, nr
, &(nr_nl
->numfields
), &(nr_nl
->len
));
724 return bzero_nr_iffinished(nr
, rc
);
726 if (unlikely(nr_nl
->numfields
> NEIGHLIST_MAX_FIELDS
))
727 return bzero_nr_iffinished(nr
, RC_CONNBROKEN
);
729 for(nr_nl
->u
=0;nr_nl
->u
<nr_nl
->numfields
;nr_nl
->u
++) {
730 nr_nl
->fields
[nr_nl
->u
].field
= 0;
734 rc
= read_fully(fd
, nr
,
735 (char *) &(nr_nl
->fields
[nr_nl
->u
].field
),
738 return bzero_nr_iffinished(nr
, rc
);
739 nr_nl
->fields
[nr_nl
->u
].field
=
740 ntohs(nr_nl
->fields
[nr_nl
->u
].field
);
745 rc
= read_len(fd
, nr
, &(nr_nl
->fieldlen
), &(nr_nl
->len
));
747 return bzero_nr_iffinished(nr
, rc
);
749 if (unlikely(nr_nl
->fieldlen
> 65535))
750 return bzero_nr_iffinished(nr
, RC_CONNBROKEN
);
752 nr_nl
->fields
[nr_nl
->u
].len
= (__u16
) nr_nl
->fieldlen
;
756 if (unlikely(field_present(nr_nl
->fields
, nr_nl
->numfields
,
757 LIST_NEIGH_FIELD_ADDR
) == 0))
758 return bzero_nr_iffinished(nr
, RC_CONNBROKEN
);
760 init(ptr
, nr_nl
->totalneighs
, nr_nl
->response_rows
);
762 for (nr_nl
->u
=0;nr_nl
->u
<nr_nl
->response_rows
;nr_nl
->u
++) {
763 bzero(&(nr_nl
->addr
[0]), ADDR_MAX_LEN
);
767 for(nr_nl
->v
=0;nr_nl
->v
<nr_nl
->numfields
;nr_nl
->v
++) {
768 nr_nl
->fieldlen
= nr_nl
->fields
[nr_nl
->v
].len
;
769 if (nr_nl
->fieldlen
== 0) {
772 rc
= read_len(fd
, nr
, &(nr_nl
->fieldlen
),
775 return bzero_nr_iffinished(nr
, rc
);
778 if (nr_nl
->fieldlen
> nr_nl
->len
)
779 return bzero_nr_iffinished(nr
, RC_CONNBROKEN
);
781 nr_nl
->len
-= nr_nl
->fieldlen
;
783 if (field_present(nr_nl
->fields
, nr_nl
->v
,
784 nr_nl
->fields
[nr_nl
->v
].field
)) {
786 } else if (nr_nl
->fields
[nr_nl
->v
].field
==
787 LIST_NEIGH_FIELD_ADDR
) {
790 rc
= read_len(fd
, nr
, &(nr_nl
->addrlen
),
793 return bzero_nr_iffinished(nr
, rc
);
795 if (unlikely(nr_nl
->addrlen
> ADDR_MAX_LEN
))
798 if (sizeof(nr_nl
->addr
) != ADDR_MAX_LEN
) {
801 return RC_CONNBROKEN
;
803 bzero(&(nr_nl
->addr
[0]), ADDR_MAX_LEN
);
807 rc
= read_fully(fd
, nr
, &(nr_nl
->addr
[0]),
811 return bzero_nr_iffinished(nr
, rc
);
812 } else if (nr_nl
->fields
[nr_nl
->v
].field
==
813 LIST_NEIGH_FIELD_LATENCY
) {
818 rc
= read_fully(fd
, nr
, &nr_nl
->latency
, 1,
821 return bzero_nr_iffinished(nr
, rc
);
823 printf("latency %d\n", (int) nr_nl
->latency
);
827 if (nr_nl
->fieldlen
> 0) {
830 rc
= read_discard(fd
, nr
, nr_nl
->fieldlen
);
832 return bzero_nr_iffinished(nr
, rc
);
838 if (nr_nl
->addrlen
> ADDR_MAX_LEN
) {
841 return RC_CONNBROKEN
;
843 next_neigh(ptr
, nr_nl
->addrlen
, &(nr_nl
->addr
[0]));
844 bzero(&(nr_nl
->addr
[0]), ADDR_MAX_LEN
);
852 int read_neigh_list(int fd
, void *ptr
,
853 void (*init
)(void *ptr
, __u32 totalneighs
, __u32 responserows
),
854 void (*next_neigh
)(void *ptr
, __u32 addrlen
, char *addr
))
856 int rc
= RC_WOULDBLOCK
;
857 struct libcor_nonblock_resumeinfo nr
;
858 bzero(&nr
, sizeof(struct libcor_nonblock_resumeinfo
));
860 rc
= read_neigh_list_nonblock(fd
, &nr
, ptr
, init
, next_neigh
);
861 if (unlikely(rc
== RC_WOULDBLOCK
)) {
868 int pass_socket(int fd
, __u64 cookie
)
872 rc
= setsockopt(fd
, SOL_COR
, COR_PASS_ON_CLOSE
, &cookie
, 8);
874 perror("pass_socket");
875 return RC_CONNBROKEN
;
883 static int send_rdsock_cmd(int fd
, __u32 cmd
, char *data
, __u32 datalen
)
892 be_datalen
= htonl(datalen
);
894 memcpy(&(hdr
[0]), (char *) &be_cmd
, 4);
895 memcpy(&(hdr
[4]), (char *) &be_datalen
, 4);
897 rc
= send_fully(fd
, hdr
, 8);
899 return RC_CONNBROKEN
;
901 rc
= send_fully(fd
, data
, datalen
);
903 return RC_CONNBROKEN
;
906 int send_rdsock_connecterror(int fd
, __u64 cookie
, __u32 error
)
910 error
= htonl(error
);
912 memcpy(&(data
[0]), (char *) &cookie
, 8);
913 memcpy(&(data
[8]), (char *) &error
, 4);
915 return send_rdsock_cmd(fd
, CRD_UTK_CONNECTERROR
, &(data
[0]), 12);
918 int send_rdsock_up(int fd
, char *addr
, __u32 addrlen
)
926 if (addr
== 0 && addrlen
!= 0)
927 return RC_CONNBROKEN
;
930 return RC_CONNBROKEN
;
932 flags
= htonll(flags
);
933 addrlenbe
= htonl(addrlen
);
935 memcpy(&(data
[0]), (char *) &flags
, 8);
936 memcpy(&(data
[8]), (char *) &addrlenbe
, 4);
938 memcpy(&(data
[12]), addr
, addrlen
);
940 return send_rdsock_cmd(fd
, CRD_UTK_UP
, &(data
[0]), 12 + addrlen
);
943 static int proc_rdsock_connect(int fd
, void *ptr
, __u32 cmd
, char *cmddata
,
944 __u32 cmdlen
, struct rdsock_opts
*opts
)
947 struct cor_sockaddr addr
;
949 memcpy((char *) &cookie
, cmddata
, 8);
951 if ((sizeof(struct cor_sockaddr
) + 8) > cmdlen
)
952 return RC_CONNBROKEN
;
954 memcpy((char *) &addr
, cmddata
+ 8, sizeof(struct cor_sockaddr
));
956 if (opts
->connect
== 0) {
957 return send_rdsock_connecterror(fd
, cookie
,
958 CONNECTERROR_NETUNREACH
);
960 return opts
->connect(fd
, ptr
, cookie
, &addr
);
964 static int proc_rdsock_cmd(int fd
, void *ptr
, __u32 cmd
, char *cmddata
,
965 __u32 cmdlen
, struct rdsock_opts
*opts
)
967 if (cmd
== CRD_KTU_CONNECT
) {
968 return proc_rdsock_connect(fd
, ptr
, cmd
, cmddata
, cmdlen
, opts
);
970 printf("error in proc_rdsock_cmd: unknown cmd: %u\n", cmd
);
971 return RC_CONNBROKEN
;
976 static int read_rdsock_cmd_nonblock(int fd
,
977 struct libcor_nonblock_resumeinfo
*nr
,
978 void *ptr
, struct rdsock_opts
*opts
)
982 struct libcor_nonblock_resumeinfo_rdsockcmd
*nr_rd
=
983 &(nr
->data
.read
.funcdata
.rdsock_cmd
);
985 if (nr
->type
== RESUME_TYPE_NONE
) {
986 bzero(nr
, sizeof(struct libcor_nonblock_resumeinfo
));
987 nr
->type
= RESUME_TYPE_READ
;
988 nr
->data
.read
.functype
= RESUME_READ_FUNC_RDSOCK_CMD
;
992 } else if (unlikely(nr
->type
!= RESUME_TYPE_READ
||
993 nr
->data
.read
.functype
!= RESUME_READ_FUNC_RDSOCK_CMD
)){
996 return RC_CONNBROKEN
;
997 } else if (unlikely(nr_rd
->fd
!= fd
|| nr_rd
->ptr
!= ptr
||
998 nr_rd
->opts
!= opts
)) {
1001 return RC_CONNBROKEN
;
1003 __u8 state
= nr_rd
->state
;
1007 } else if (state
== 2) {
1009 } else if (unlikely(state
!= 0)) {
1012 return RC_CONNBROKEN
;
1016 if (sizeof(nr_rd
->buf
) != 8) {
1019 return RC_CONNBROKEN
;
1022 rc
= read_fully(fd
, nr
, (char *) &(nr_rd
->buf
[0]), 8, 0);
1024 return RC_CONNBROKEN
;
1026 ((char *) &(nr_rd
->cmd
))[0] = nr_rd
->buf
[0];
1027 ((char *) &(nr_rd
->cmd
))[1] = nr_rd
->buf
[1];
1028 ((char *) &(nr_rd
->cmd
))[2] = nr_rd
->buf
[2];
1029 ((char *) &(nr_rd
->cmd
))[3] = nr_rd
->buf
[3];
1030 ((char *) &(nr_rd
->cmddatalen
))[0] = nr_rd
->buf
[4];
1031 ((char *) &(nr_rd
->cmddatalen
))[1] = nr_rd
->buf
[5];
1032 ((char *) &(nr_rd
->cmddatalen
))[2] = nr_rd
->buf
[6];
1033 ((char *) &(nr_rd
->cmddatalen
))[3] = nr_rd
->buf
[7];
1035 nr_rd
->cmd
= ntohl(nr_rd
->cmd
);
1036 nr_rd
->cmddatalen
= ntohl(nr_rd
->cmddatalen
);
1038 if (nr_rd
->cmddatalen
> 65536)
1041 nr_rd
->cmddata
= malloc(nr_rd
->cmddatalen
);
1042 if (nr_rd
->cmddata
== 0)
1047 rc
= read_fully(fd
, nr
, nr_rd
->cmddata
, nr_rd
->cmddatalen
, 0);
1053 proc_rdsock_cmd(fd
, ptr
, nr_rd
->cmd
, nr_rd
->cmddata
, nr_rd
->cmddatalen
,
1057 free(nr_rd
->cmddata
);
1063 rc
= read_discard(fd
, nr
, nr_rd
->cmddatalen
);
1070 int read_rdsock_cmd(int fd
, void *ptr
, struct rdsock_opts
*opts
)
1072 int rc
= RC_WOULDBLOCK
;
1073 struct libcor_nonblock_resumeinfo nr
;
1074 bzero(&nr
, sizeof(struct libcor_nonblock_resumeinfo
));
1076 rc
= read_rdsock_cmd_nonblock(fd
, &nr
, ptr
, opts
);
1077 if (unlikely(rc
== RC_WOULDBLOCK
)) {