The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6378393308bc6bd81fb871dacf6b03cf1a390d8b

commit 6378393308bc6bd81fb871dacf6b03cf1a390d8b
Author:     John Baldwin <j...@freebsd.org>
AuthorDate: 2021-12-22 18:35:46 +0000
Commit:     John Baldwin <j...@freebsd.org>
CommitDate: 2021-12-22 18:43:11 +0000

    Add an internal libiscsiutil library.
    
    Move some of the code duplicated between ctld(8) and iscsid(8) into a
    libiscsiutil library.
    
    Sharing the low-level PDU code did require having a
    'struct connection' base class with a method table to permit separate
    initiator vs target behavior (e.g. in handling proxy PDUs).
    
    Reviewed by:    mav, emaste
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D33544
---
 lib/Makefile                               |   1 +
 lib/libiscsiutil/Makefile                  |  10 +
 {usr.sbin/ctld => lib/libiscsiutil}/chap.c |   6 +-
 lib/libiscsiutil/connection.c              |  53 ++++
 {usr.sbin/ctld => lib/libiscsiutil}/keys.c |   6 +-
 lib/libiscsiutil/libiscsiutil.h            | 148 ++++++++++
 {usr.sbin/ctld => lib/libiscsiutil}/log.c  |   6 +-
 {usr.sbin/ctld => lib/libiscsiutil}/pdu.c  |  96 ++-----
 lib/libiscsiutil/utils.c                   |  44 +++
 rescue/rescue/Makefile                     |   3 +
 share/mk/bsd.libnames.mk                   |   1 +
 share/mk/src.libnames.mk                   |   4 +
 usr.sbin/ctld/Makefile                     |   7 +-
 usr.sbin/ctld/ctld.c                       |  86 ++++--
 usr.sbin/ctld/ctld.h                       | 102 +------
 usr.sbin/ctld/discovery.c                  |   8 +-
 usr.sbin/ctld/kernel.c                     |  27 +-
 usr.sbin/ctld/login.c                      |  51 ++--
 usr.sbin/iscsid/Makefile                   |   5 +-
 usr.sbin/iscsid/chap.c                     | 423 -----------------------------
 usr.sbin/iscsid/discovery.c                |  14 +-
 usr.sbin/iscsid/iscsid.c                   | 173 ++++++++----
 usr.sbin/iscsid/iscsid.h                   |  97 +------
 usr.sbin/iscsid/keys.c                     | 199 --------------
 usr.sbin/iscsid/log.c                      | 202 --------------
 usr.sbin/iscsid/login.c                    |  74 ++---
 usr.sbin/iscsid/pdu.c                      | 309 ---------------------
 27 files changed, 583 insertions(+), 1572 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index bd28b974c673..43c345daf356 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -63,6 +63,7 @@ SUBDIR=       ${SUBDIR_BOOTSTRAP} \
        libgeom \
        libifconfig \
        libipsec \
+       libiscsiutil \
        libjail \
        libkiconv \
        libkvm \
diff --git a/lib/libiscsiutil/Makefile b/lib/libiscsiutil/Makefile
new file mode 100644
index 000000000000..9ec625970eae
--- /dev/null
+++ b/lib/libiscsiutil/Makefile
@@ -0,0 +1,10 @@
+LIB=           iscsiutil
+INTERNALLIB=
+PACKAGE=       iscsi
+
+INCS=          libiscsiutil.h
+
+SRCS=          chap.c connection.c keys.c log.c pdu.c utils.c
+CFLAGS+=       -I${SRCTOP}/sys/dev/iscsi
+
+.include <bsd.lib.mk>
diff --git a/usr.sbin/ctld/chap.c b/lib/libiscsiutil/chap.c
similarity index 99%
rename from usr.sbin/ctld/chap.c
rename to lib/libiscsiutil/chap.c
index 7b57b7080c97..b33fef220106 100644
--- a/usr.sbin/ctld/chap.c
+++ b/lib/libiscsiutil/chap.c
@@ -26,12 +26,8 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
  */
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
@@ -39,7 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <resolv.h>
 #include <md5.h>
 
-#include "ctld.h"
+#include "libiscsiutil.h"
 
 static void
 chap_compute_md5(const char id, const char *secret,
diff --git a/lib/libiscsiutil/connection.c b/lib/libiscsiutil/connection.c
new file mode 100644
index 000000000000..7dc50574644c
--- /dev/null
+++ b/lib/libiscsiutil/connection.c
@@ -0,0 +1,53 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2012 The FreeBSD Foundation
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include "libiscsiutil.h"
+
+void
+connection_init(struct connection *conn, const struct connection_ops *ops,
+       bool use_proxy)
+{
+       memset(conn, 0, sizeof(*conn));
+       conn->conn_ops = ops;
+       conn->conn_use_proxy = use_proxy;
+
+       /*
+        * Default values, from RFC 3720, section 12.
+        */
+       conn->conn_header_digest = CONN_DIGEST_NONE;
+       conn->conn_data_digest = CONN_DIGEST_NONE;
+       conn->conn_immediate_data = true;
+       conn->conn_max_recv_data_segment_length = 8192;
+       conn->conn_max_send_data_segment_length = 8192;
+       conn->conn_max_burst_length = 262144;
+       conn->conn_first_burst_length = 65536;
+}
diff --git a/usr.sbin/ctld/keys.c b/lib/libiscsiutil/keys.c
similarity index 98%
rename from usr.sbin/ctld/keys.c
rename to lib/libiscsiutil/keys.c
index f28e333bcd81..8011b0a25329 100644
--- a/usr.sbin/ctld/keys.c
+++ b/lib/libiscsiutil/keys.c
@@ -26,18 +26,14 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
  */
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "ctld.h"
+#include "libiscsiutil.h"
 
 struct keys *
 keys_new(void)
diff --git a/lib/libiscsiutil/libiscsiutil.h b/lib/libiscsiutil/libiscsiutil.h
new file mode 100644
index 000000000000..79c79872b2e6
--- /dev/null
+++ b/lib/libiscsiutil/libiscsiutil.h
@@ -0,0 +1,148 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2012 The FreeBSD Foundation
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LIBISCSIUTIL_H__
+#define        __LIBISCSIUTIL_H__
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+struct connection_ops;
+
+#define        CONN_DIGEST_NONE                0
+#define        CONN_DIGEST_CRC32C              1
+
+struct connection {
+       const struct connection_ops *conn_ops;
+       int             conn_socket;
+       uint8_t         conn_isid[6];
+       uint16_t        conn_tsih;
+       uint32_t        conn_cmdsn;
+       uint32_t        conn_statsn;
+       int             conn_header_digest;
+       int             conn_data_digest;
+       bool            conn_immediate_data;
+       bool            conn_use_proxy;
+       int             conn_max_recv_data_segment_length;
+       int             conn_max_send_data_segment_length;
+       int             conn_max_burst_length;
+       int             conn_first_burst_length;
+};
+
+struct pdu {
+       struct connection *pdu_connection;
+       struct iscsi_bhs *pdu_bhs;
+       char            *pdu_data;
+       size_t          pdu_data_len;
+};
+
+struct connection_ops {
+       bool            (*timed_out)(void);
+       void            (*pdu_receive_proxy)(struct pdu *);
+       void            (*pdu_send_proxy)(struct pdu *);
+       void            (*fail)(const struct connection *, const char *);
+};
+
+#define        KEYS_MAX                1024
+
+struct keys {
+       char            *keys_names[KEYS_MAX];
+       char            *keys_values[KEYS_MAX];
+       char            *keys_data;
+       size_t          keys_data_len;
+};
+
+#define        CHAP_CHALLENGE_LEN      1024
+#define        CHAP_DIGEST_LEN         16 /* Equal to MD5 digest size. */
+
+struct chap {
+       unsigned char   chap_id;
+       char            chap_challenge[CHAP_CHALLENGE_LEN];
+       char            chap_response[CHAP_DIGEST_LEN];
+};
+
+struct rchap {
+       char            *rchap_secret;
+       unsigned char   rchap_id;
+       void            *rchap_challenge;
+       size_t          rchap_challenge_len;
+};
+
+struct chap            *chap_new(void);
+char                   *chap_get_id(const struct chap *chap);
+char                   *chap_get_challenge(const struct chap *chap);
+int                    chap_receive(struct chap *chap, const char *response);
+int                    chap_authenticate(struct chap *chap,
+                           const char *secret);
+void                   chap_delete(struct chap *chap);
+
+struct rchap           *rchap_new(const char *secret);
+int                    rchap_receive(struct rchap *rchap,
+                           const char *id, const char *challenge);
+char                   *rchap_get_response(struct rchap *rchap);
+void                   rchap_delete(struct rchap *rchap);
+
+struct keys            *keys_new(void);
+void                   keys_delete(struct keys *key);
+void                   keys_load(struct keys *keys, const struct pdu *pdu);
+void                   keys_save(struct keys *keys, struct pdu *pdu);
+const char             *keys_find(struct keys *keys, const char *name);
+void                   keys_add(struct keys *keys,
+                           const char *name, const char *value);
+void                   keys_add_int(struct keys *keys,
+                           const char *name, int value);
+
+struct pdu             *pdu_new(struct connection *ic);
+struct pdu             *pdu_new_response(struct pdu *request);
+int                    pdu_ahs_length(const struct pdu *pdu);
+int                    pdu_data_segment_length(const struct pdu *pdu);
+void                   pdu_set_data_segment_length(struct pdu *pdu,
+                           uint32_t len);
+void                   pdu_receive(struct pdu *request);
+void                   pdu_send(struct pdu *response);
+void                   pdu_delete(struct pdu *ip);
+
+void                   connection_init(struct connection *conn,
+                           const struct connection_ops *ops, bool use_proxy);
+
+void                   log_init(int level);
+void                   log_set_peer_name(const char *name);
+void                   log_set_peer_addr(const char *addr);
+void                   log_err(int, const char *, ...)
+                           __dead2 __printflike(2, 3);
+void                   log_errx(int, const char *, ...)
+                           __dead2 __printflike(2, 3);
+void                   log_warn(const char *, ...) __printflike(1, 2);
+void                   log_warnx(const char *, ...) __printflike(1, 2);
+void                   log_debugx(const char *, ...) __printflike(1, 2);
+
+char                   *checked_strdup(const char *);
+
+#endif /* !__LIBISCSIUTIL_H__ */
diff --git a/usr.sbin/ctld/log.c b/lib/libiscsiutil/log.c
similarity index 98%
rename from usr.sbin/ctld/log.c
rename to lib/libiscsiutil/log.c
index 94e014293a61..7d7a13bb11f2 100644
--- a/usr.sbin/ctld/log.c
+++ b/lib/libiscsiutil/log.c
@@ -26,12 +26,8 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
  */
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 #include <errno.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -40,7 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <syslog.h>
 #include <vis.h>
 
-#include "ctld.h"
+#include "libiscsiutil.h"
 
 static int log_level = 0;
 static char *peer_name = NULL;
diff --git a/usr.sbin/ctld/pdu.c b/lib/libiscsiutil/pdu.c
similarity index 77%
rename from usr.sbin/ctld/pdu.c
rename to lib/libiscsiutil/pdu.c
index 04691556b997..ed5ee5b71766 100644
--- a/usr.sbin/ctld/pdu.c
+++ b/lib/libiscsiutil/pdu.c
@@ -35,26 +35,22 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <assert.h>
+#include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
-#include "ctld.h"
-#include "iscsi_proto.h"
+#include <iscsi_proto.h>
+#include "libiscsiutil.h"
 
-#ifdef ICL_KERNEL_PROXY
-#include <sys/ioctl.h>
-#endif
-
-extern bool proxy_mode;
-
-static int
+int
 pdu_ahs_length(const struct pdu *pdu)
 {
 
        return (pdu->pdu_bhs->bhs_total_ahs_len * 4);
 }
 
-static int
+int
 pdu_data_segment_length(const struct pdu *pdu)
 {
        uint32_t len = 0;
@@ -68,7 +64,7 @@ pdu_data_segment_length(const struct pdu *pdu)
        return (len);
 }
 
-static void
+void
 pdu_set_data_segment_length(struct pdu *pdu, uint32_t len)
 {
 
@@ -102,40 +98,6 @@ pdu_new_response(struct pdu *request)
        return (pdu_new(request->pdu_connection));
 }
 
-#ifdef ICL_KERNEL_PROXY
-
-static void
-pdu_receive_proxy(struct pdu *pdu)
-{
-       struct connection *conn;
-       size_t len;
-
-       assert(proxy_mode);
-       conn = pdu->pdu_connection;
-
-       kernel_receive(pdu);
-
-       len = pdu_ahs_length(pdu);
-       if (len > 0)
-               log_errx(1, "protocol error: non-empty AHS");
-
-       len = pdu_data_segment_length(pdu);
-       assert(len <= (size_t)conn->conn_max_recv_data_segment_length);
-       pdu->pdu_data_len = len;
-}
-
-static void
-pdu_send_proxy(struct pdu *pdu)
-{
-
-       assert(proxy_mode);
-
-       pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
-       kernel_send(pdu);
-}
-
-#endif /* ICL_KERNEL_PROXY */
-
 static size_t
 pdu_padding(const struct pdu *pdu)
 {
@@ -147,18 +109,24 @@ pdu_padding(const struct pdu *pdu)
 }
 
 static void
-pdu_read(int fd, char *data, size_t len)
+pdu_read(const struct connection *conn, char *data, size_t len)
 {
        ssize_t ret;
 
        while (len > 0) {
-               ret = read(fd, data, len);
+               ret = read(conn->conn_socket, data, len);
                if (ret < 0) {
-                       if (timed_out())
+                       if (conn->conn_ops->timed_out()) {
+                               conn->conn_ops->fail(conn,
+                                   "Login Phase timeout");
                                log_errx(1, "exiting due to timeout");
+                       }
+                       conn->conn_ops->fail(conn, strerror(errno));
                        log_err(1, "read");
-               } else if (ret == 0)
+               } else if (ret == 0) {
+                       conn->conn_ops->fail(conn, "connection lost");
                        log_errx(1, "read: connection lost");
+               }
                len -= ret;
                data += ret;
        }
@@ -171,16 +139,11 @@ pdu_receive(struct pdu *pdu)
        size_t len, padding;
        char dummy[4];
 
-#ifdef ICL_KERNEL_PROXY
-       if (proxy_mode)
-               return (pdu_receive_proxy(pdu));
-#endif
-
-       assert(proxy_mode == false);
        conn = pdu->pdu_connection;
+       if (conn->conn_use_proxy)
+               return (conn->conn_ops->pdu_receive_proxy(pdu));
 
-       pdu_read(conn->conn_socket, (char *)pdu->pdu_bhs,
-           sizeof(*pdu->pdu_bhs));
+       pdu_read(conn, (char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs));
 
        len = pdu_ahs_length(pdu);
        if (len > 0)
@@ -199,13 +162,12 @@ pdu_receive(struct pdu *pdu)
                if (pdu->pdu_data == NULL)
                        log_err(1, "malloc");
 
-               pdu_read(conn->conn_socket, (char *)pdu->pdu_data,
-                   pdu->pdu_data_len);
+               pdu_read(conn, (char *)pdu->pdu_data, pdu->pdu_data_len);
 
                padding = pdu_padding(pdu);
                if (padding != 0) {
                        assert(padding < sizeof(dummy));
-                       pdu_read(conn->conn_socket, (char *)dummy, padding);
+                       pdu_read(conn, (char *)dummy, padding);
                }
        }
 }
@@ -213,18 +175,16 @@ pdu_receive(struct pdu *pdu)
 void
 pdu_send(struct pdu *pdu)
 {
+       struct connection *conn;
        ssize_t ret, total_len;
        size_t padding;
        uint32_t zero = 0;
        struct iovec iov[3];
        int iovcnt;
 
-#ifdef ICL_KERNEL_PROXY
-       if (proxy_mode)
-               return (pdu_send_proxy(pdu));
-#endif
-
-       assert(proxy_mode == false);
+       conn = pdu->pdu_connection;
+       if (conn->conn_use_proxy)
+               return (conn->conn_ops->pdu_send_proxy(pdu));
 
        pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
        iov[0].iov_base = pdu->pdu_bhs;
@@ -248,9 +208,9 @@ pdu_send(struct pdu *pdu)
                }
        }
 
-       ret = writev(pdu->pdu_connection->conn_socket, iov, iovcnt);
+       ret = writev(conn->conn_socket, iov, iovcnt);
        if (ret < 0) {
-               if (timed_out())
+               if (conn->conn_ops->timed_out())
                        log_errx(1, "exiting due to timeout");
                log_err(1, "writev");
        }
diff --git a/lib/libiscsiutil/utils.c b/lib/libiscsiutil/utils.c
new file mode 100644
index 000000000000..1e04490c477c
--- /dev/null
+++ b/lib/libiscsiutil/utils.c
@@ -0,0 +1,44 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2012 The FreeBSD Foundation
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include "libiscsiutil.h"
+
+char *
+checked_strdup(const char *s)
+{
+       char *c;
+
+       c = strdup(s);
+       if (c == NULL)
+               log_err(1, "strdup");
+       return (c);
+}
diff --git a/rescue/rescue/Makefile b/rescue/rescue/Makefile
index 90aaea3cb709..783b5bbd7721 100644
--- a/rescue/rescue/Makefile
+++ b/rescue/rescue/Makefile
@@ -236,6 +236,9 @@ CRUNCH_LIBS+= -lm
 .if ${MK_ISCSI} != "no"
 CRUNCH_PROGS_usr.bin+= iscsictl
 CRUNCH_PROGS_usr.sbin+=        iscsid
+
+CRUNCH_LIBS+=          ${OBJTOP}/lib/libiscsiutil/libiscsiutil.a
+CRUNCH_BUILDOPTS+=     CRUNCH_CFLAGS+=-I${OBJTOP}/lib/libiscsiutil
 .endif
 
 .include <bsd.crunchgen.mk>
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index f71664bf5858..45710b203ddc 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -83,6 +83,7 @@ LIBIBVERBS?=  ${LIBDESTDIR}${LIBDIR_BASE}/libibverbs.a
 LIBICP?=       ${LIBDESTDIR}${LIBDIR_BASE}/libicp.a
 LIBIPSEC?=     ${LIBDESTDIR}${LIBDIR_BASE}/libipsec.a
 LIBIPT?=       ${LIBDESTDIR}${LIBDIR_BASE}/libipt.a
+LIBISCSIUTIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libiscsiutil.a
 LIBJAIL?=      ${LIBDESTDIR}${LIBDIR_BASE}/libjail.a
 LIBKADM5CLNT?= ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5clnt.a
 LIBKADM5SRV?=  ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5srv.a
diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk
index 385e8616a82d..cf6c41887791 100644
--- a/share/mk/src.libnames.mk
+++ b/share/mk/src.libnames.mk
@@ -44,6 +44,7 @@ _INTERNALLIBS=        \
                fifolog \
                ifconfig \
                ipf \
+               iscsiutil \
                lpr \
                lua \
                lutok \
@@ -556,6 +557,9 @@ LIBIFCONFIG?=       
${LIBIFCONFIGDIR}/libifconfig${PIE_SUFFIX}.a
 LIBIPFDIR=     ${_LIB_OBJTOP}/sbin/ipf/libipf
 LIBIPF?=       ${LIBIPFDIR}/libipf${PIE_SUFFIX}.a
 
+LIBISCSIUTILDIR=       ${_LIB_OBJTOP}/lib/libiscsiutil
+LIBISCSIUTIL?= ${LIBISCSIUTILDIR}/libiscsiutil${PIE_SUFFIX}.a
+
 LIBTELNETDIR=  ${_LIB_OBJTOP}/lib/libtelnet
 LIBTELNET?=    ${LIBTELNETDIR}/libtelnet${PIE_SUFFIX}.a
 
diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile
index ec207f024ab1..5f80ba026204 100644
--- a/usr.sbin/ctld/Makefile
+++ b/usr.sbin/ctld/Makefile
@@ -7,16 +7,17 @@ CFLAGS+=-I${SRCTOP}/contrib/libucl/include
 
 PACKAGE=       iscsi
 PROG=          ctld
-SRCS=          chap.c ctld.c discovery.c isns.c kernel.c keys.c log.c
-SRCS+=         login.c parse.y pdu.c token.l y.tab.h uclparse.c
+SRCS=          ctld.c discovery.c isns.c kernel.c
+SRCS+=         login.c parse.y token.l y.tab.h uclparse.c
 CFLAGS+=       -I${.CURDIR}
 CFLAGS+=       -I${SRCTOP}/sys
 CFLAGS+=       -I${SRCTOP}/sys/cam/ctl
 CFLAGS+=       -I${SRCTOP}/sys/dev/iscsi
+CFLAGS+=       -I${SRCTOP}/lib/libiscsiutil
 #CFLAGS+=      -DICL_KERNEL_PROXY
 MAN=           ctld.8 ctl.conf.5
 
-LIBADD=                bsdxml md sbuf util ucl m nv
+LIBADD=                bsdxml iscsiutil md sbuf util ucl m nv
 
 YFLAGS+=       -v
 CLEANFILES=    y.tab.c y.tab.h y.output
diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c
index c37181ff00d0..3f4bca632512 100644
--- a/usr.sbin/ctld/ctld.c
+++ b/usr.sbin/ctld/ctld.c
@@ -54,6 +54,13 @@ __FBSDID("$FreeBSD$");
 #include "ctld.h"
 #include "isns.h"
 
+static bool    timed_out(void);
+#ifdef ICL_KERNEL_PROXY
+static void    pdu_receive_proxy(struct pdu *pdu);
+static void    pdu_send_proxy(struct pdu *pdu);
+#endif /* ICL_KERNEL_PROXY */
+static void    pdu_fail(const struct connection *conn, const char *reason);
+
 bool proxy_mode = false;
 
 static volatile bool sighup_received = false;
@@ -63,6 +70,15 @@ static volatile bool sigalrm_received = false;
 static int nchildren = 0;
 static uint16_t last_portal_group_tag = 0xff;
 
+static struct connection_ops conn_ops = {
+       .timed_out = timed_out,
+#ifdef ICL_KERNEL_PROXY
+       .pdu_receive_proxy = pdu_receive_proxy,
+       .pdu_send_proxy = pdu_send_proxy,
+#endif
+       .fail = pdu_fail,
+};
+
 static void
 usage(void)
 {
@@ -72,17 +88,6 @@ usage(void)
        exit(1);
 }
 
-char *
-checked_strdup(const char *s)
-{
-       char *c;
-
-       c = strdup(s);
-       if (c == NULL)
-               log_err(1, "strdup");
-       return (c);
-}
-
 struct conf *
 conf_new(void)
 {
@@ -1632,29 +1637,60 @@ option_set(struct option *o, const char *value)
        o->o_value = checked_strdup(value);
 }
 
-static struct connection *
+#ifdef ICL_KERNEL_PROXY
+
+static void
+pdu_receive_proxy(struct pdu *pdu)
+{
+       struct connection *conn;
+       size_t len;
+
+       assert(proxy_mode);
+       conn = pdu->pdu_connection;
+
+       kernel_receive(pdu);
+
+       len = pdu_ahs_length(pdu);
+       if (len > 0)
+               log_errx(1, "protocol error: non-empty AHS");
+
+       len = pdu_data_segment_length(pdu);
+       assert(len <= (size_t)conn->conn_max_recv_data_segment_length);
+       pdu->pdu_data_len = len;
+}
+
+static void
+pdu_send_proxy(struct pdu *pdu)
+{
+
+       assert(proxy_mode);
+
+       pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
+       kernel_send(pdu);
+}
+
+#endif /* ICL_KERNEL_PROXY */
+
+static void
+pdu_fail(const struct connection *conn __unused, const char *reason __unused)
+{
+}
+
+static struct ctld_connection *
 connection_new(struct portal *portal, int fd, const char *host,
     const struct sockaddr *client_sa)
 {
-       struct connection *conn;
+       struct ctld_connection *conn;
 
        conn = calloc(1, sizeof(*conn));
        if (conn == NULL)
                log_err(1, "calloc");
+       connection_init(&conn->conn, &conn_ops, proxy_mode);
+       conn->conn.conn_socket = fd;
        conn->conn_portal = portal;
-       conn->conn_socket = fd;
        conn->conn_initiator_addr = checked_strdup(host);
        memcpy(&conn->conn_initiator_sa, client_sa, client_sa->sa_len);
 
-       /*
-        * Default values, from RFC 3720, section 12.
-        */
-       conn->conn_max_recv_data_segment_length = 8192;
-       conn->conn_max_send_data_segment_length = 8192;
-       conn->conn_max_burst_length = 262144;
-       conn->conn_first_burst_length = 65536;
-       conn->conn_immediate_data = true;
-
        return (conn);
 }
 
@@ -2296,7 +2332,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
        return (cumulated_error);
 }
 
-bool
+static bool
 timed_out(void)
 {
 
@@ -2407,7 +2443,7 @@ static void
 handle_connection(struct portal *portal, int fd,
     const struct sockaddr *client_sa, bool dont_fork)
 {
-       struct connection *conn;
+       struct ctld_connection *conn;
        int error;
        pid_t pid;
        char host[NI_MAXHOST + 1];
diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h
index 4ff8f0e638ac..293f5378592f 100644
--- a/usr.sbin/ctld/ctld.h
+++ b/usr.sbin/ctld/ctld.h
@@ -39,6 +39,7 @@
 #endif
 #include <sys/socket.h>
 #include <stdbool.h>
+#include <libiscsiutil.h>
 #include <libutil.h>
 
 #define        DEFAULT_CONFIG_PATH             "/etc/ctl.conf"
@@ -229,83 +230,25 @@ struct conf {
 #define        CONN_SESSION_TYPE_DISCOVERY     1
 #define        CONN_SESSION_TYPE_NORMAL        2
 
-#define        CONN_DIGEST_NONE                0
-#define        CONN_DIGEST_CRC32C              1
-
-struct connection {
+struct ctld_connection {
+       struct connection       conn;
        struct portal           *conn_portal;
        struct port             *conn_port;
        struct target           *conn_target;
-       int                     conn_socket;
        int                     conn_session_type;
        char                    *conn_initiator_name;
        char                    *conn_initiator_addr;
        char                    *conn_initiator_alias;
        uint8_t                 conn_initiator_isid[6];
        struct sockaddr_storage conn_initiator_sa;
-       uint32_t                conn_cmdsn;
-       uint32_t                conn_statsn;
        int                     conn_max_recv_data_segment_limit;
        int                     conn_max_send_data_segment_limit;
        int                     conn_max_burst_limit;
        int                     conn_first_burst_limit;
-       int                     conn_max_recv_data_segment_length;
-       int                     conn_max_send_data_segment_length;
-       int                     conn_max_burst_length;
-       int                     conn_first_burst_length;
-       int                     conn_immediate_data;
-       int                     conn_header_digest;
-       int                     conn_data_digest;
        const char              *conn_user;
        struct chap             *conn_chap;
 };
 
-struct pdu {
-       struct connection       *pdu_connection;
-       struct iscsi_bhs        *pdu_bhs;
-       char                    *pdu_data;
-       size_t                  pdu_data_len;
-};
-
-#define        KEYS_MAX        1024
-
-struct keys {
-       char            *keys_names[KEYS_MAX];
-       char            *keys_values[KEYS_MAX];
-       char            *keys_data;
-       size_t          keys_data_len;
-};
-
-#define        CHAP_CHALLENGE_LEN      1024
-#define        CHAP_DIGEST_LEN         16 /* Equal to MD5 digest size. */
-
-struct chap {
-       unsigned char   chap_id;
-       char            chap_challenge[CHAP_CHALLENGE_LEN];
-       char            chap_response[CHAP_DIGEST_LEN];
-};
-
-struct rchap {
-       char            *rchap_secret;
-       unsigned char   rchap_id;
-       void            *rchap_challenge;
-       size_t          rchap_challenge_len;
-};
-
-struct chap            *chap_new(void);
-char                   *chap_get_id(const struct chap *chap);
-char                   *chap_get_challenge(const struct chap *chap);
-int                    chap_receive(struct chap *chap, const char *response);
-int                    chap_authenticate(struct chap *chap,
-                           const char *secret);
-void                   chap_delete(struct chap *chap);
-
-struct rchap           *rchap_new(const char *secret);
-int                    rchap_receive(struct rchap *rchap,
-                           const char *id, const char *challenge);
-char                   *rchap_get_response(struct rchap *rchap);
-void                   rchap_delete(struct rchap *rchap);
-
 int                    parse_conf(struct conf *conf, const char *path);
 int                    uclparse_conf(struct conf *conf, const char *path);
 
@@ -412,7 +355,7 @@ void                        kernel_init(void);
 int                    kernel_lun_add(struct lun *lun);
 int                    kernel_lun_modify(struct lun *lun);
 int                    kernel_lun_remove(struct lun *lun);
-void                   kernel_handoff(struct connection *conn);
+void                   kernel_handoff(struct ctld_connection *conn);
 void                   kernel_limits(const char *offload,
                            int *max_recv_data_segment_length,
                            int *max_send_data_segment_length,
@@ -433,40 +376,11 @@ void                      kernel_send(struct pdu *pdu);
 void                   kernel_receive(struct pdu *pdu);
 #endif
 
-struct keys            *keys_new(void);
-void                   keys_delete(struct keys *keys);
-void                   keys_load(struct keys *keys, const struct pdu *pdu);
-void                   keys_save(struct keys *keys, struct pdu *pdu);
-const char             *keys_find(struct keys *keys, const char *name);
-void                   keys_add(struct keys *keys,
-                           const char *name, const char *value);
-void                   keys_add_int(struct keys *keys,
-                           const char *name, int value);
-
-struct pdu             *pdu_new(struct connection *conn);
-struct pdu             *pdu_new_response(struct pdu *request);
-void                   pdu_delete(struct pdu *pdu);
-void                   pdu_receive(struct pdu *request);
-void                   pdu_send(struct pdu *response);
-
-void                   login(struct connection *conn);
-
-void                   discovery(struct connection *conn);
-
-void                   log_init(int level);
-void                   log_set_peer_name(const char *name);
-void                   log_set_peer_addr(const char *addr);
-void                   log_err(int, const char *, ...)
-                           __dead2 __printflike(2, 3);
-void                   log_errx(int, const char *, ...)
-                           __dead2 __printflike(2, 3);
-void                   log_warn(const char *, ...) __printflike(1, 2);
-void                   log_warnx(const char *, ...) __printflike(1, 2);
-void                   log_debugx(const char *, ...) __printflike(1, 2);
-
-char                   *checked_strdup(const char *);
+void                   login(struct ctld_connection *conn);
+
+void                   discovery(struct ctld_connection *conn);
+
 bool                   valid_iscsi_name(const char *name);
 void                   set_timeout(int timeout, int fatal);
-bool                   timed_out(void);
 
 #endif /* !CTLD_H */
diff --git a/usr.sbin/ctld/discovery.c b/usr.sbin/ctld/discovery.c
*** 2321 LINES SKIPPED ***

Reply via email to