more
authorStefan Metzmacher <metze@samba.org>
Thu, 29 Sep 2016 00:29:11 +0000 (02:29 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 1 Jun 2018 12:35:06 +0000 (14:35 +0200)
libcli/smb/smb_direct.c
libcli/smb/smb_transport_tcp.c

index 91a4e1d1781e29717a007342733f68dba271cda7..506b432425fa23a14b34e660bd841ffeea81fa62 100644 (file)
@@ -216,7 +216,7 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        c->state.max_receive_size    = SMB_DIRECT_IO_MAX_DATA;
        c->state.max_fragmented_size = 1048576;
        c->state.max_read_write_size = 0;
-       c->state.receive_credit_max  = 2;
+       c->state.receive_credit_max  = 128;//255;
        c->state.send_credit_target  = 255;
        c->state.keep_alive_internal = 5;
 
@@ -289,8 +289,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        smb_set_close_on_exec(c->ibv.comp_channel->fd);
        set_blocking(c->ibv.comp_channel->fd, false);
 
-       c->ibv.init_attr.cap.max_send_wr = 2;
-       c->ibv.init_attr.cap.max_recv_wr = 2;
+       c->ibv.init_attr.cap.max_send_wr = c->state.send_credit_target; // more for RDMA READ/WRITE??
+       c->ibv.init_attr.cap.max_recv_wr = c->state.receive_credit_max; // more for RDMA READ/WRITE??
        c->ibv.init_attr.cap.max_recv_sge = 2;
        c->ibv.init_attr.cap.max_send_sge = 2;
        c->ibv.init_attr.qp_type = IBV_QPT_RC;
@@ -375,6 +375,18 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        return c;
 }
 
+static void smb_direct_connection_debug_credits(struct smb_direct_connection *c,
+                                               const char *location, const char *func)
+{
+       DEBUG(0,("%s:%s: CREDITS: RMAX[%u] RTARGET[%u] R[%u] STARGET[%u] S[%u]\n",
+               location, func,
+               c->state.receive_credit_max,
+               c->state.receive_credit_target,
+               c->state.receive_credits,
+               c->state.send_credit_target,
+               c->state.send_credits));
+}
+
 static int smb_direct_connection_destructor(struct smb_direct_connection *c)
 {
        TALLOC_FREE(c->sock.fde);
@@ -446,6 +458,7 @@ static int smb_direct_connection_post_recv(struct smb_direct_connection *c)
        int ret;
 
 DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+smb_direct_connection_debug_credits(c, __location__, __func__);
        if (c->r2s.idle == NULL) {
 DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                return 0;
@@ -487,6 +500,7 @@ static int smb_direct_connection_post_send(struct smb_direct_connection *c)
        int ret;
 
 DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+smb_direct_connection_debug_credits(c, __location__, __func__);
        if (c->s2r.ready == NULL) {
 DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                return 0;
@@ -512,6 +526,7 @@ DEBUG(0,("%s:%s: TODO: REMOVE me ...here...\n", __location__, __func__));
                next = io->next;
 
                if (c->state.send_credits == 0) {
+smb_direct_connection_debug_credits(c, __location__, __func__);
                        break;
                }
 
@@ -525,6 +540,8 @@ DEBUG(0,("%s:%s: TODO: REMOVE me ...here...\n", __location__, __func__));
                granted -= c->state.receive_credits;
                granted = MIN(granted, c->state.receive_credit_target);
                c->state.receive_credits += granted;
+smb_direct_connection_debug_credits(c, __location__, __func__);
+
 //             if (c->state.receive_credits == 0) {
 //                     granted = 1;
 //                     c->state.receive_credits += granted;
@@ -556,6 +573,9 @@ DEBUG(0,("%s:%s: TODO: REMOVE me ...here...\n", __location__, __func__));
                }
                DLIST_REMOVE(c->s2r.ready, io);
                DLIST_ADD_END(posted, io);
+               DEBUG(0,("%s:%s: POST SEND[%p] data_length[%u] remaining_length[%u]\n",
+                       __location__, __FUNCTION__, io,
+                       (unsigned)io->data_length, (unsigned)io->remaining_length));
        }
 
        last = DLIST_TAIL(posted);
@@ -582,10 +602,11 @@ static int smb_direct_connection_post_keep(struct smb_direct_connection *c)
        struct smb_direct_io *io = NULL;
        int ret;
 
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: KEEP posted[%p] ready[%p] idle[%p]\n",
+       __location__, __func__, ));
        if (c->s2r.posted != NULL) {
 DEBUG(0,("%s:%s: here...\n", __location__, __func__));
-               return 0;
+//             return 0;
        }
 
        if (c->s2r.ready != NULL) {
@@ -621,7 +642,7 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
 }
 static int smb_direct_connection_setup_readv(struct smb_direct_connection *c)
 {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_READABLE on\n", __location__, __func__));
        TEVENT_FD_READABLE(c->sock.fde);
        // TODO: immediate_event?? may skips a syscall.
        return 0;
@@ -629,7 +650,7 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
 
 static int smb_direct_connection_setup_writev(struct smb_direct_connection *c)
 {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_WRITEABLE on\n", __location__, __func__));
        TEVENT_FD_WRITEABLE(c->sock.fde);
        // TODO: immediate_event?? may skips a syscall.
        return 0;
@@ -1599,7 +1620,7 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
        struct ibv_wc wc;
        int ret;
        uint16_t credits_requested;
-       uint16_t credits_granted;
+       uint32_t credits_granted;
        uint16_t flags;
        uint32_t data_offset;
        struct smb_direct_io *io = NULL;
@@ -1673,8 +1694,9 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
 
        switch (wc.opcode) {
        case IBV_WC_SEND:
-               DEBUG(0,("%s:%s: GOT SEND[%p] ret[%d] errno[%d]\n",
-                       __location__, __FUNCTION__, io, ret, errno));
+               DEBUG(0,("%s:%s: GOT SEND[%p] data_length[%u] remaining_length[%u] ret[%d] errno[%d]\n",
+                       __location__, __FUNCTION__, io,
+                       (unsigned)io->data_length, (unsigned)io->remaining_length, ret, errno));
                DLIST_REMOVE(c->s2r.posted, io);
                DLIST_ADD_END(c->s2r.idle, io);
 
@@ -1692,10 +1714,15 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
        case IBV_WC_RECV:
                DEBUG(0,("%s:%s: GOT RECV[%p] ret[%d] errno[%d]\n",
                        __location__, __FUNCTION__, io, ret, errno));
-               if (wc.byte_len >= c->state.max_receive_size) {
+               if (wc.byte_len > c->state.max_receive_size) {
                        status = NT_STATUS_INVALID_NETWORK_RESPONSE;
-                       DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
-                               __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+                       DEBUG(0,("%s:%s: wc.byte_len[%u/0x%x] max_receive_size[%u/0x%x] ret[%d] errno[%d] status[%s]\n",
+                               __location__, __FUNCTION__,
+                               (unsigned)wc.byte_len,
+                               (unsigned)wc.byte_len,
+                               (unsigned)c->state.max_receive_size,
+                               (unsigned)c->state.max_receive_size,
+                               ret, errno, nt_errstr(status)));
                        smb_direct_connection_disconnect(c, status);
                        return;
                }
@@ -1717,13 +1744,6 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
                        return;
                }
                credits_granted = SVAL(io->smbd_hdr, 0x02);
-               if (credits_granted == 0) {
-                       status = NT_STATUS_INVALID_NETWORK_RESPONSE;
-                       DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
-                               __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
-                       smb_direct_connection_disconnect(c, status);
-                       return;
-               }
                flags = SVAL(io->smbd_hdr, 0x04);
                io->remaining_length = IVAL(io->smbd_hdr, 0x08);
                data_offset = IVAL(io->smbd_hdr, 0x0C);
@@ -1731,8 +1751,18 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
 
                c->state.receive_credits -= 1;
                c->state.receive_credit_target = credits_requested;
-               c->state.send_credits += credits_granted;
 
+               credits_granted += c->state.send_credits;
+               if (credits_granted > c->state.send_credit_target) {
+                       status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+                       DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
+                               __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+                       smb_direct_connection_disconnect(c, status);
+                       return;
+               }
+               c->state.send_credits = credits_granted;
+
+smb_direct_connection_debug_credits(c, __location__, __func__);
                if (data_offset == 0) {
                        if (wc.byte_len != 0x14) {
                                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
@@ -1753,8 +1783,15 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
                        }
                        return;
                } else if (data_offset == 0x18) {
-                       if (io->data_length >= (c->state.max_receive_size - data_offset)) {
+                       if (io->data_length > (c->state.max_receive_size - data_offset)) {
                                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+                       DEBUG(0,("%s:%s: io->data_length[%u/0x%x] max_receive_size-data_offset[%u/0x%x] ret[%d] errno[%d] status[%s]\n",
+                               __location__, __FUNCTION__,
+                               (unsigned)io->data_length,
+                               (unsigned)io->data_length,
+                               (unsigned)c->state.max_receive_size - data_offset,
+                               (unsigned)c->state.max_receive_size - data_offset,
+                               ret, errno, nt_errstr(status)));
                                DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
                                        __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
                                smb_direct_connection_disconnect(c, status);
@@ -1792,6 +1829,10 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
                        io->iov[0].iov_base = io->data;
                        io->iov[0].iov_len = io->data_length;
                        io->iov_count = 1;
+                       DEBUG(0,("%s:%s: CONTINUE[%p] io->data_length[%u] io->remaining_length[%u]\n",
+                               __location__, __func__, io,
+                               (unsigned)io->data_length,
+                               (unsigned)io->remaining_length));
                } else {
                        uint64_t total_length = io->data_length + io->remaining_length;
 
@@ -1810,6 +1851,12 @@ static void smb_direct_connection_ibv_handler(struct tevent_context *ev,
                        io->iov[1].iov_base = io->data;
                        io->iov[1].iov_len = io->data_length;
                        io->iov_count = 2;
+                       DEBUG(0,("%s:%s: START[%p] total_length[%u] io->data_length[%u] io->remaining_length[%u]\n",
+                               __location__, __func__, io, (unsigned)total_length,
+                               (unsigned)io->data_length,
+                               (unsigned)io->remaining_length));
+
+                       c->r2s.remaining_length = io->remaining_length;;
                }
 
                if (c->state.receive_credits == 0) {
@@ -1878,14 +1925,14 @@ static void smb_direct_connection_sock_handler(struct tevent_context *ev,
        int ret;
        bool ok;
 
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
  do_write:
        if (fde_flags & TEVENT_FD_WRITE) {
                if (c->r2s.out != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        io = c->r2s.out;
                } else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        io = c->r2s.ready;
                        if (io != NULL) {
                                DLIST_REMOVE(c->r2s.ready, io);
@@ -1896,11 +1943,11 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                if (io != NULL) {
                        ssize_t sret;
 
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        sret = writev(c->sock.fd, io->iov, io->iov_count);
                        if (sret == -1) {
                                if (errno == EAGAIN) { // and more...
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_NOT_WRITEABLE writev...\n", __location__, __func__));
                                        TEVENT_FD_WRITEABLE(c->sock.fde);
                                        goto done_write;
                                }
@@ -1924,17 +1971,17 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        if (io->iov_count == 0) {
                                c->r2s.out = NULL;
                                DLIST_ADD_END(c->r2s.idle, io);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                                goto do_write;
                        }
                } else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_NOT_WRITEABLE\n", __location__, __func__));
                        TEVENT_FD_NOT_WRITEABLE(c->sock.fde);
                }
        }
 
  done_write:
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        ret = smb_direct_connection_post_recv(c);
        if (ret != 0) {
                status = map_nt_error_from_unix_common(errno);
@@ -1947,17 +1994,17 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
  do_read:
        if (fde_flags & TEVENT_FD_READ) {
                if (c->s2r.in != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        io = c->s2r.in;
                } else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        io = c->s2r.idle;
                        if (io != NULL) {
                                DLIST_REMOVE(c->s2r.idle, io);
                                c->s2r.in = io;
 
                                if (c->s2r.remaining_length > 0) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                                        /*
                                         * We need to continue to get
                                         * the incomplete packet.
@@ -1972,8 +2019,12 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                                        io->iov[0].iov_base = io->data;
                                        io->iov[0].iov_len = io->data_length;
                                        io->iov_count = 1;
+                       DEBUG(0,("%s:%s: CONTINUE[%p] io->data_length[%u] io->remaining_length[%u]\n",
+                               __location__, __func__, io,
+                               (unsigned)io->data_length,
+                               (unsigned)io->remaining_length));
                                } else {
-       DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+       DEBUG(0,("%s:%s: WAIT[%p] for NBT\n", __location__, __func__, io));
                                        /*
                                         * For a new packet we need to get the length
                                         * first.
@@ -1991,11 +2042,11 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                if (io != NULL) {
                        ssize_t sret;
 
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        sret = readv(c->sock.fd, io->iov, io->iov_count);
                        if (sret == -1) {
                                if (errno == EAGAIN) { // and more...
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_READABLE...\n", __location__, __func__));
                                        TEVENT_FD_READABLE(c->sock.fde);
                                        goto done_read;
                                }
@@ -2025,7 +2076,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
 
                        if (io->iov_count == 0) {
                                if (io->data_length != 0) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: FINISH[%p] io->data_length[%u] io->remaining_length[%u]\n",
+       __location__, __func__, io, (unsigned)io->data_length, (unsigned)io->remaining_length));
                                        /*
                                         * We managed to read the whole fragment
                                         * which is ready to be posted into the
@@ -2036,7 +2088,7 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                                        goto do_read;
                                }
 
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                                c->s2r.remaining_length = smb_len_tcp(io->nbt_hdr);
                                if (c->s2r.remaining_length > c->state.max_fragmented_size) { //correct direction
                                        status = NT_STATUS_INVALID_BUFFER_SIZE;
@@ -2050,27 +2102,31 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                                                      c->s2r.remaining_length);
                                io->remaining_length = c->s2r.remaining_length;
                                io->remaining_length -= io->data_length;
-                               c->s2r.remaining_length = io->remaining_length;
 
                                io->iov = io->_iov_array;
                                io->iov[0].iov_base = io->data;
                                io->iov[0].iov_len = io->data_length;
                                io->iov_count = 1;
 
+                       DEBUG(0,("%s:%s: AFTER[%p] total[%u] io->data_length[%u] io->remaining_length[%u]\n",
+                               __location__, __func__, io, (unsigned)c->s2r.remaining_length,
+                               (unsigned)io->data_length,
+                               (unsigned)io->remaining_length));
+                               c->s2r.remaining_length = io->remaining_length;
                                /*
                                 * try to read the reset immediately.
                                 */
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                                goto do_read;
                        }
                } else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_NOT_READABLE...\n", __location__, __func__));
                        TEVENT_FD_NOT_READABLE(c->sock.fde);
                }
        }
 
  done_read:
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        ret = smb_direct_connection_post_send(c);
        if (ret != 0) {
                status = map_nt_error_from_unix_common(errno);
@@ -2086,9 +2142,9 @@ NTSTATUS smb_direct_connection_setup_events(struct smb_direct_connection *c,
 {
        uint16_t sock_fde_flags = TEVENT_FD_READ;
 
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        if (c->r2s.out != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                sock_fde_flags |= TEVENT_FD_WRITE;
        }
 
@@ -2097,7 +2153,7 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                TALLOC_FREE(c->sock.fde);
                TALLOC_FREE(c->ibv.fde_channel);
                TALLOC_FREE(c->rdma.fde_channel);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        }
 
        if (tevent_fd_get_flags(c->rdma.fde_channel) == 0) {
@@ -2105,11 +2161,11 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                TALLOC_FREE(c->sock.fde);
                TALLOC_FREE(c->ibv.fde_channel);
                TALLOC_FREE(c->rdma.fde_channel);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        }
 
        if (ev == NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                c->last_ev = NULL;
                TALLOC_FREE(c->sock.fde);
                TALLOC_FREE(c->ibv.fde_channel);
@@ -2118,12 +2174,12 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        }
 
        if (ev == c->last_ev) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                return NT_STATUS_OK;
        }
 
        if (c->last_ev != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                return NT_STATUS_INVALID_PARAMETER_MIX;
        }
 
index 6fa3c69da9fa6c7e5d3097fa18995efd7f1bf535..52e85ce3e901a7df27af9f387fce60e7b869304a 100644 (file)
@@ -109,6 +109,8 @@ static struct tevent_req *smb_transport_tcp_write_pdu_send(TALLOC_CTX *mem_ctx,
 
        _smb_setlen_tcp(state->hdr, to_write);
 
+                       DEBUG(0,("%s:%s: to_write[%u]\n",
+                               __location__, __func__, (unsigned)to_write));
        /* we make a copy of the vector so that we can modify it */
        state->vector = talloc_array(state, struct iovec, 1 + count);
        if (tevent_req_nomem(state->vector, req)) {
@@ -203,6 +205,7 @@ static void smb_transport_tcp_read_pdu_done(struct tevent_req *subreq)
                struct smb_transport_tcp_read_pdu_state);
        ssize_t ret;
        int sys_errno;
+       uint32_t len;
 
        ret = read_smb_recv(subreq, state, &state->inbuf, &sys_errno);
        TALLOC_FREE(subreq);
@@ -212,6 +215,10 @@ static void smb_transport_tcp_read_pdu_done(struct tevent_req *subreq)
                return;
        }
 
+       len = smb_len_tcp(state->inbuf);
+                       DEBUG(0,("%s:%s: read ret[%u] len_tcp[%u]\n",
+                               __location__, __func__, (unsigned)ret, len));
+       dump_data(0, state->inbuf, ret);
        tevent_req_done(req);
 }