xref: /illumos-gate/usr/src/lib/libsmbfs/smb/iod_wk.c (revision adee6784)
1613a2f6bSGordon Ross /*
2613a2f6bSGordon Ross  * CDDL HEADER START
3613a2f6bSGordon Ross  *
4613a2f6bSGordon Ross  * The contents of this file are subject to the terms of the
5613a2f6bSGordon Ross  * Common Development and Distribution License (the "License").
6613a2f6bSGordon Ross  * You may not use this file except in compliance with the License.
7613a2f6bSGordon Ross  *
8613a2f6bSGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9613a2f6bSGordon Ross  * or http://www.opensolaris.org/os/licensing.
10613a2f6bSGordon Ross  * See the License for the specific language governing permissions
11613a2f6bSGordon Ross  * and limitations under the License.
12613a2f6bSGordon Ross  *
13613a2f6bSGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14613a2f6bSGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15613a2f6bSGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16613a2f6bSGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17613a2f6bSGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18613a2f6bSGordon Ross  *
19613a2f6bSGordon Ross  * CDDL HEADER END
20613a2f6bSGordon Ross  */
21613a2f6bSGordon Ross 
22613a2f6bSGordon Ross /*
23613a2f6bSGordon Ross  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24613a2f6bSGordon Ross  * Use is subject to license terms.
2540c0e231SGordon Ross  *
2640c0e231SGordon Ross  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
27613a2f6bSGordon Ross  */
28613a2f6bSGordon Ross 
29613a2f6bSGordon Ross /*
30613a2f6bSGordon Ross  * Functions called by the IO deamon (IOD).
31613a2f6bSGordon Ross  * Here in the library to simplify testing.
32613a2f6bSGordon Ross  */
33613a2f6bSGordon Ross 
34613a2f6bSGordon Ross #include <errno.h>
35613a2f6bSGordon Ross #include <fcntl.h>
36613a2f6bSGordon Ross #include <stdio.h>
37613a2f6bSGordon Ross #include <string.h>
38613a2f6bSGordon Ross #include <stdlib.h>
39613a2f6bSGordon Ross #include <unistd.h>
40613a2f6bSGordon Ross #include <libintl.h>
41613a2f6bSGordon Ross 
42613a2f6bSGordon Ross #include <sys/byteorder.h>
43613a2f6bSGordon Ross #include <sys/types.h>
44613a2f6bSGordon Ross #include <sys/fcntl.h>
45613a2f6bSGordon Ross #include <sys/ioctl.h>
46613a2f6bSGordon Ross #include <sys/time.h>
47613a2f6bSGordon Ross #include <sys/socket.h>
48613a2f6bSGordon Ross 
49613a2f6bSGordon Ross #include <netinet/in.h>
50613a2f6bSGordon Ross #include <netinet/tcp.h>
51613a2f6bSGordon Ross #include <arpa/inet.h>
52613a2f6bSGordon Ross 
53613a2f6bSGordon Ross #include <netsmb/smb.h>
54613a2f6bSGordon Ross #include <netsmb/smb_lib.h>
55613a2f6bSGordon Ross #include <netsmb/netbios.h>
56613a2f6bSGordon Ross #include <netsmb/nb_lib.h>
57613a2f6bSGordon Ross #include <netsmb/smb_dev.h>
58613a2f6bSGordon Ross 
59613a2f6bSGordon Ross #include "charsets.h"
60613a2f6bSGordon Ross #include "private.h"
61613a2f6bSGordon Ross 
62613a2f6bSGordon Ross /*
6340c0e231SGordon Ross  * The user agent (smbiod) calls smb_iod_connect for the first
6440c0e231SGordon Ross  * connection to some server, and if that succeeds, will start a
6540c0e231SGordon Ross  * thread running this function, passing the smb_ctx_t
6640c0e231SGordon Ross  *
6740c0e231SGordon Ross  * This thread now enters the driver and stays there, reading
6840c0e231SGordon Ross  * network responses as long as the connection is alive.
69613a2f6bSGordon Ross  */
70613a2f6bSGordon Ross int
smb_iod_work(smb_ctx_t * ctx)71613a2f6bSGordon Ross smb_iod_work(smb_ctx_t *ctx)
72613a2f6bSGordon Ross {
73613a2f6bSGordon Ross 	smbioc_ssn_work_t *work = &ctx->ct_work;
7440c0e231SGordon Ross 	int	err = 0;
75613a2f6bSGordon Ross 
76613a2f6bSGordon Ross 	DPRINT("server: %s", ctx->ct_srvname);
77613a2f6bSGordon Ross 
78613a2f6bSGordon Ross 	/*
79613a2f6bSGordon Ross 	 * This is the reader / reconnect loop.
80613a2f6bSGordon Ross 	 *
81613a2f6bSGordon Ross 	 * We could start with state "idle", but
82613a2f6bSGordon Ross 	 * we know someone wants a connection to
83613a2f6bSGordon Ross 	 * this server, so start in "vcactive".
84613a2f6bSGordon Ross 	 *
85613a2f6bSGordon Ross 	 * XXX: Add some syslog calls in here?
86613a2f6bSGordon Ross 	 */
87613a2f6bSGordon Ross 
88613a2f6bSGordon Ross 	for (;;) {
89613a2f6bSGordon Ross 
9040c0e231SGordon Ross 		DPRINT("state: %s",
9140c0e231SGordon Ross 		    smb_iod_state_name(work->wk_out_state));
9240c0e231SGordon Ross 
9340c0e231SGordon Ross 		switch (work->wk_out_state) {
94613a2f6bSGordon Ross 		case SMBIOD_ST_IDLE:
95613a2f6bSGordon Ross 			/*
96613a2f6bSGordon Ross 			 * Wait for driver requests to arrive
97613a2f6bSGordon Ross 			 * for this VC, then return here.
98613a2f6bSGordon Ross 			 * Next state is normally RECONNECT.
99613a2f6bSGordon Ross 			 */
10040c0e231SGordon Ross 			DPRINT("Call _ioc_idle...");
1018329232eSGordon Ross 			if (nsmb_ioctl(ctx->ct_dev_fd,
10240c0e231SGordon Ross 			    SMBIOC_IOD_IDLE, work) == -1) {
103613a2f6bSGordon Ross 				err = errno;
104613a2f6bSGordon Ross 				DPRINT("ioc_idle: err %d", err);
105613a2f6bSGordon Ross 				goto out;
106613a2f6bSGordon Ross 			}
107*adee6784SGordon Ross 			DPRINT("Ret. from _ioc_idle");
108613a2f6bSGordon Ross 			continue;
109613a2f6bSGordon Ross 
110613a2f6bSGordon Ross 		case SMBIOD_ST_RECONNECT:
11140c0e231SGordon Ross 			DPRINT("Call _iod_connect...");
112613a2f6bSGordon Ross 			err = smb_iod_connect(ctx);
11340c0e231SGordon Ross 			if (err == 0)
114613a2f6bSGordon Ross 				continue;
11540c0e231SGordon Ross 			DPRINT("iod_connect: err %d", err);
116613a2f6bSGordon Ross 			/*
117613a2f6bSGordon Ross 			 * If the error was EAUTH, retry is
118613a2f6bSGordon Ross 			 * not likely to succeed either, so
119613a2f6bSGordon Ross 			 * just exit this thread.  The user
120613a2f6bSGordon Ross 			 * will need to run smbutil to get
121613a2f6bSGordon Ross 			 * a new thread with new auth info.
122613a2f6bSGordon Ross 			 */
123*adee6784SGordon Ross 			if (err == EAUTH) {
124*adee6784SGordon Ross 				DPRINT("iod_connect: EAUTH (give up)");
125613a2f6bSGordon Ross 				goto out;
126*adee6784SGordon Ross 			}
127613a2f6bSGordon Ross 			/*
128*adee6784SGordon Ross 			 * Reconnect failed.  Notify any requests
129*adee6784SGordon Ross 			 * that we're not connected, and delay.
130*adee6784SGordon Ross 			 * Next state will be IDLE or RECONNECT.
131613a2f6bSGordon Ross 			 */
13240c0e231SGordon Ross 			DPRINT("Call _iod_rcfail...");
1338329232eSGordon Ross 			if (nsmb_ioctl(ctx->ct_dev_fd,
13440c0e231SGordon Ross 			    SMBIOC_IOD_RCFAIL, work) == -1) {
135613a2f6bSGordon Ross 				err = errno;
13640c0e231SGordon Ross 				DPRINT("iod_rcfail: err %d", err);
137613a2f6bSGordon Ross 				goto out;
138613a2f6bSGordon Ross 			}
139613a2f6bSGordon Ross 			continue;
140613a2f6bSGordon Ross 
14140c0e231SGordon Ross 		case SMBIOD_ST_AUTHOK:
14240c0e231SGordon Ross 			/*
14340c0e231SGordon Ross 			 * This is where we enter the driver and
14440c0e231SGordon Ross 			 * stay there.  While the connection is up
14540c0e231SGordon Ross 			 * the VC will have SMBIOD_ST_VCACTIVE
14640c0e231SGordon Ross 			 */
14740c0e231SGordon Ross 			DPRINT("Call _iod_work...");
1488329232eSGordon Ross 			if (nsmb_ioctl(ctx->ct_dev_fd,
149613a2f6bSGordon Ross 			    SMBIOC_IOD_WORK, work) == -1) {
150613a2f6bSGordon Ross 				err = errno;
15140c0e231SGordon Ross 				DPRINT("iod_work: err %d", err);
152613a2f6bSGordon Ross 				goto out;
153613a2f6bSGordon Ross 			}
154*adee6784SGordon Ross 			DPRINT("Ret. from _ioc_work");
155613a2f6bSGordon Ross 			continue;
156613a2f6bSGordon Ross 
157613a2f6bSGordon Ross 		case SMBIOD_ST_DEAD:
158*adee6784SGordon Ross 			DPRINT("got state=DEAD");
159613a2f6bSGordon Ross 			err = 0;
160613a2f6bSGordon Ross 			goto out;
161613a2f6bSGordon Ross 
162613a2f6bSGordon Ross 		default:
16340c0e231SGordon Ross 			DPRINT("Unexpected state: %d (%s)",
16440c0e231SGordon Ross 			    work->wk_out_state,
16540c0e231SGordon Ross 			    smb_iod_state_name(work->wk_out_state));
166613a2f6bSGordon Ross 			err = EFAULT;
167613a2f6bSGordon Ross 			goto out;
168613a2f6bSGordon Ross 		}
169613a2f6bSGordon Ross 	}
170613a2f6bSGordon Ross 
171613a2f6bSGordon Ross out:
172613a2f6bSGordon Ross 	if (ctx->ct_dev_fd != -1) {
1738329232eSGordon Ross 		nsmb_close(ctx->ct_dev_fd);
174613a2f6bSGordon Ross 		ctx->ct_dev_fd = -1;
175613a2f6bSGordon Ross 	}
176613a2f6bSGordon Ross 
177613a2f6bSGordon Ross 	return (err);
178613a2f6bSGordon Ross }
179