4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
28 #include <sys/types.h>
29 #include <sys/param.h>
31 #include <sys/sunddi.h>
33 #include <sys/varargs.h>
34 #include <sys/modctl.h>
35 #include <sys/pathname.h>
36 #include <sys/vnode.h>
37 #include <sys/socket.h>
38 #include <sys/ksocket.h>
39 #undef mem_free /* XXX Remove this after we convert everything to kmem_alloc */
41 #include <smbsrv/smb_vops.h>
42 #include <smbsrv/smb.h>
43 #include <smbsrv/smb_kproto.h>
44 #include <smbsrv/smb_kstat.h>
47 * SMB Network Socket API
49 * smb_socreate: Creates an socket based on domain/type.
50 * smb_soshutdown: Disconnect a socket created with smb_socreate
51 * smb_sodestroy: Release resources associated with a socket
52 * smb_sosend: Send the contents of a buffer on a socket
53 * smb_sorecv: Receive data into a buffer from a socket
54 * smb_iov_sosend: Send the contents of an iovec on a socket
55 * smb_iov_sorecv: Receive data into an iovec from a socket
59 smb_socreate(int domain
, int type
, int protocol
)
64 err
= ksocket_socket(&sock
, domain
, type
, protocol
, KSOCKET_SLEEP
,
74 * smb_soshutdown will disconnect the socket and prevent subsequent PDU
75 * reception and transmission. The sonode still exists but its state
76 * gets modified to indicate it is no longer connected. Calls to
77 * smb_sorecv/smb_iov_sorecv will return so smb_soshutdown can be used
78 * regain control of a thread stuck in smb_sorecv.
81 smb_soshutdown(ksocket_t so
)
83 (void) ksocket_shutdown(so
, SHUT_RDWR
, CRED());
87 * smb_sodestroy releases all resources associated with a socket previously
88 * created with smb_socreate. The socket must be shutdown using smb_soshutdown
89 * before the socket is destroyed with smb_sodestroy, otherwise undefined
90 * behavior will result.
93 smb_sodestroy(ksocket_t so
)
95 (void) ksocket_close(so
, CRED());
99 smb_sorecv(ksocket_t so
, void *msg
, size_t len
)
107 if ((err
= ksocket_recv(so
, msg
, len
, MSG_WAITALL
, &recvd
,
112 /* Successful receive */
113 return ((recvd
== len
) ? 0 : -1);
117 * smb_net_txl_constructor
119 * Transmit list constructor
122 smb_net_txl_constructor(smb_txlst_t
*txl
)
124 ASSERT(txl
->tl_magic
!= SMB_TXLST_MAGIC
);
126 mutex_init(&txl
->tl_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
127 cv_init(&txl
->tl_wait_cv
, NULL
, CV_DEFAULT
, NULL
);
128 txl
->tl_active
= B_FALSE
;
129 txl
->tl_magic
= SMB_TXLST_MAGIC
;
133 * smb_net_txl_destructor
135 * Transmit list destructor
138 smb_net_txl_destructor(smb_txlst_t
*txl
)
140 ASSERT(txl
->tl_magic
== SMB_TXLST_MAGIC
);
143 cv_destroy(&txl
->tl_wait_cv
);
144 mutex_destroy(&txl
->tl_mutex
);
150 * This routine puts the transmit buffer passed in on the wire.
151 * If another thread is already sending, block on the CV.
154 smb_net_send_uio(smb_session_t
*s
, struct uio
*uio
)
158 smb_txlst_t
*txl
= &s
->s_txlst
;
161 DTRACE_PROBE1(send__wait__start
, struct smb_session_t
*, s
);
164 * Wait for our turn to send.
166 mutex_enter(&txl
->tl_mutex
);
167 while (txl
->tl_active
)
168 cv_wait(&txl
->tl_wait_cv
, &txl
->tl_mutex
);
169 txl
->tl_active
= B_TRUE
;
170 mutex_exit(&txl
->tl_mutex
);
172 DTRACE_PROBE1(send__wait__done
, struct smb_session_t
*, s
);
177 * This should block until we've sent it all,
178 * or given up due to errors (socket closed).
180 bzero(&msg
, sizeof (msg
));
181 msg
.msg_iov
= uio
->uio_iov
;
182 msg
.msg_iovlen
= uio
->uio_iovcnt
;
183 while (uio
->uio_resid
> 0) {
184 rc
= ksocket_sendmsg(s
->sock
, &msg
, 0, &sent
, CRED());
187 uio
->uio_resid
-= sent
;
190 mutex_enter(&txl
->tl_mutex
);
191 txl
->tl_active
= B_FALSE
;
192 cv_signal(&txl
->tl_wait_cv
);
193 mutex_exit(&txl
->tl_mutex
);