]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libcli/smb: add smbXcli_transport_tstream()
authorStefan Metzmacher <metze@samba.org>
Wed, 7 May 2025 18:29:55 +0000 (20:29 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 18 Jun 2025 17:52:37 +0000 (17:52 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
libcli/smb/smbXcli_base.c
libcli/smb/smbXcli_base.h
libcli/smb/wscript

index 4727849a5ef5209dd3308805662937df63a20141..46bdedadb83c8b985105f5735c3072e0bdfd2aea 100644 (file)
@@ -23,6 +23,8 @@
 #include "../lib/async_req/async_sock.h"
 #include "../lib/util/tevent_ntstatus.h"
 #include "../lib/util/tevent_unix.h"
+#include "lib/tsocket/tsocket.h"
+#include "source3/lib/util_tsock.h"
 #include "lib/util/util_net.h"
 #include "lib/util/dlinklist.h"
 #include "lib/util/iov_buf.h"
@@ -48,6 +50,7 @@ struct smbXcli_tcon;
 struct smbXcli_transport {
        struct smb_transport transport;
        int sock_fd;
+       struct tstream_context *tstream;
        struct samba_sockaddr laddr;
        struct samba_sockaddr raddr;
 
@@ -346,10 +349,112 @@ static int smbXcli_transport_destructor(struct smbXcli_transport *xtp)
                close(xtp->sock_fd);
                xtp->sock_fd = -1;
        }
-
+       TALLOC_FREE(xtp->tstream);
        return 0;
 }
 
+static struct tevent_req *smbXcli_transport_tstream_writev_send(
+                               TALLOC_CTX *mem_ctx,
+                               struct tevent_context *ev,
+                               struct smbXcli_transport *xtp,
+                               struct tevent_queue *queue,
+                               struct iovec *iov,
+                               int count)
+{
+       return tstream_writev_queue_send(mem_ctx,
+                                        ev,
+                                        xtp->tstream,
+                                        queue,
+                                        iov,
+                                        count);
+}
+
+static ssize_t smbXcli_transport_tstream_writev_recv(struct tevent_req *req,
+                                                int *perrno)
+{
+       return tstream_writev_queue_recv(req, perrno);
+}
+
+static struct tevent_req *smbXcli_transport_tstream_read_smb_send(
+                               TALLOC_CTX *mem_ctx,
+                               struct tevent_context *ev,
+                               struct smbXcli_transport *xtp)
+{
+       return tstream_read_packet_send(mem_ctx,
+                                       ev,
+                                       xtp->tstream,
+                                       4,
+                                       read_smb_more,
+                                       NULL);
+}
+
+static ssize_t smbXcli_transport_tstream_read_smb_recv(
+                               struct tevent_req *req,
+                               TALLOC_CTX *mem_ctx,
+                               uint8_t **pbuf,
+                               int *perrno)
+{
+       return tstream_read_packet_recv(req, mem_ctx, pbuf, perrno);
+}
+
+static struct tevent_req *smbXcli_transport_tstream_monitor_send(
+                               TALLOC_CTX *mem_ctx,
+                               struct tevent_context *ev,
+                               struct smbXcli_transport *xtp)
+{
+       return tstream_monitor_send(mem_ctx,
+                                   ev,
+                                   xtp->tstream);
+}
+
+static int smbXcli_transport_tstream_monitor_recv(struct tevent_req *req)
+{
+       int sys_errno = 0;
+       int ret;
+
+       ret = tstream_monitor_recv(req, &sys_errno);
+       if (ret == 0) {
+               sys_errno = EPIPE;
+       }
+       if (sys_errno == 0) {
+               sys_errno = EPIPE;
+       }
+
+       return sys_errno;
+}
+
+struct smbXcli_transport *smbXcli_transport_tstream(TALLOC_CTX *mem_ctx,
+                                                   struct tstream_context **pstream,
+                                                   const struct samba_sockaddr *laddr,
+                                                   const struct samba_sockaddr *raddr,
+                                                   const struct smb_transport *tp)
+{
+       struct smbXcli_transport *xtp = NULL;
+
+       xtp = talloc_zero(mem_ctx, struct smbXcli_transport);
+       if (xtp == NULL) {
+               return NULL;
+       }
+
+       xtp->transport = *tp;
+       xtp->sock_fd = -1;
+
+       xtp->laddr = *laddr;
+       xtp->raddr = *raddr;
+
+       xtp->tstream = talloc_move(xtp, pstream);
+
+       xtp->writev_send_fn = smbXcli_transport_tstream_writev_send;
+       xtp->writev_recv_fn = smbXcli_transport_tstream_writev_recv;
+       xtp->read_smb_send_fn = smbXcli_transport_tstream_read_smb_send;
+       xtp->read_smb_recv_fn = smbXcli_transport_tstream_read_smb_recv;
+       xtp->monitor_send_fn = smbXcli_transport_tstream_monitor_send;
+       xtp->monitor_recv_fn = smbXcli_transport_tstream_monitor_recv;
+
+       talloc_set_destructor(xtp, smbXcli_transport_destructor);
+       return xtp;
+}
+
 static struct tevent_req *smbXcli_transport_bsd_writev_send(
                                TALLOC_CTX *mem_ctx,
                                struct tevent_context *ev,
@@ -602,6 +707,15 @@ bool smbXcli_conn_is_connected(struct smbXcli_conn *conn)
                return false;
        }
 
+       if (conn->transport->tstream != NULL) {
+               ret = tstream_pending_bytes(conn->transport->tstream);
+               if (ret < 0) {
+                       return false;
+               }
+
+               return true;
+       }
+
        if (conn->transport->sock_fd == -1) {
                return false;
        }
@@ -667,6 +781,10 @@ bool smbXcli_conn_support_passthrough(struct smbXcli_conn *conn)
 
 void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options)
 {
+       if (conn->transport->sock_fd == -1) {
+               return;
+       }
+
        set_socket_options(conn->transport->sock_fd, options);
 }
 
@@ -1362,10 +1480,12 @@ void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
 {
        struct smbXcli_session *session;
        int sock_fd = conn->transport->sock_fd;
+       struct tstream_context *tstream = conn->transport->tstream;
 
        tevent_queue_stop(conn->outgoing);
 
        conn->transport->sock_fd = -1;
+       conn->transport->tstream = NULL;
 
        session = conn->sessions;
        if (talloc_array_length(conn->pending) == 0) {
@@ -1493,6 +1613,7 @@ void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
        if (sock_fd != -1) {
                close(sock_fd);
        }
+       TALLOC_FREE(tstream);
 }
 
 struct smbXcli_conn_monitor_state {
index 6460ac6eba098dd8d87cd2d60a1de4c0a1f5139b..7f28aeb3cab90a3290581c31d9babe7f71c4ee1c 100644 (file)
@@ -41,6 +41,14 @@ struct smb2_create_blobs;
 struct smb_create_returns;
 struct smb_transport;
 struct smb311_capabilities;
+struct samba_sockaddr;
+struct tstream_context;
+
+struct smbXcli_transport *smbXcli_transport_tstream(TALLOC_CTX *mem_ctx,
+                                                   struct tstream_context **pstream,
+                                                   const struct samba_sockaddr *laddr,
+                                                   const struct samba_sockaddr *raddr,
+                                                   const struct smb_transport *tp);
 
 struct smbXcli_transport *smbXcli_transport_bsd(TALLOC_CTX *mem_ctx,
                                                int *_fd,
index 86f14680741c7452a64065f1840c797a969b23a4..48f84e5f72ff7f1154d1ed0984d75d0c9c18ef53 100644 (file)
@@ -38,7 +38,7 @@ def build(bld):
     ''',
     deps='''
         LIBCRYPTO gnutls NDR_SMB2_LEASE_STRUCT samba-errors gensec krb5samba
-        LIBASYNC_REQ GNUTLS_HELPERS NDR_IOCTL
+        LIBASYNC_REQ util_tsock GNUTLS_HELPERS NDR_IOCTL
     ''',
     public_deps='talloc tevent samba-util iov_buf',
     private_library=True,