1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Functions called by the IO deamon (IOD). 29 * Here in the library to simplify testing. 30 */ 31 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <stdlib.h> 37 #include <unistd.h> 38 #include <libintl.h> 39 40 #include <sys/byteorder.h> 41 #include <sys/types.h> 42 #include <sys/fcntl.h> 43 #include <sys/ioctl.h> 44 #include <sys/time.h> 45 #include <sys/socket.h> 46 47 #include <netinet/in.h> 48 #include <netinet/tcp.h> 49 #include <arpa/inet.h> 50 51 #include <netsmb/smb.h> 52 #include <netsmb/smb_lib.h> 53 #include <netsmb/netbios.h> 54 #include <netsmb/nb_lib.h> 55 #include <netsmb/smb_dev.h> 56 57 #include "charsets.h" 58 #include "private.h" 59 60 /* 61 * Be the reader thread for this VC. 62 */ 63 int 64 smb_iod_work(smb_ctx_t *ctx) 65 { 66 smbioc_ssn_work_t *work = &ctx->ct_work; 67 int vcst, err = 0; 68 69 DPRINT("server: %s", ctx->ct_srvname); 70 71 /* Calle should have opened these */ 72 if (ctx->ct_tran_fd == -1 || ctx->ct_dev_fd == -1) { 73 err = EINVAL; 74 goto out; 75 } 76 77 /* 78 * This is the reader / reconnect loop. 79 * 80 * We could start with state "idle", but 81 * we know someone wants a connection to 82 * this server, so start in "vcactive". 83 * 84 * XXX: Add some syslog calls in here? 85 */ 86 vcst = SMBIOD_ST_VCACTIVE; 87 88 for (;;) { 89 90 switch (vcst) { 91 case SMBIOD_ST_IDLE: 92 /* 93 * Wait for driver requests to arrive 94 * for this VC, then return here. 95 * Next state is normally RECONNECT. 96 */ 97 DPRINT("state: idle"); 98 if (ioctl(ctx->ct_dev_fd, 99 SMBIOC_IOD_IDLE, &vcst) == -1) { 100 err = errno; 101 DPRINT("ioc_idle: err %d", err); 102 goto out; 103 } 104 continue; 105 106 case SMBIOD_ST_RECONNECT: 107 DPRINT("state: reconnect"); 108 err = smb_iod_connect(ctx); 109 if (err == 0) { 110 vcst = SMBIOD_ST_VCACTIVE; 111 continue; 112 } 113 DPRINT("_iod_connect: err %d", err); 114 /* 115 * If the error was EAUTH, retry is 116 * not likely to succeed either, so 117 * just exit this thread. The user 118 * will need to run smbutil to get 119 * a new thread with new auth info. 120 */ 121 if (err == EAUTH) 122 goto out; 123 vcst = SMBIOD_ST_RCFAILED; 124 continue; 125 126 case SMBIOD_ST_RCFAILED: 127 DPRINT("state: rcfailed"); 128 /* 129 * Reconnect failed. Kill off any 130 * requests waiting in the driver, 131 * then get ready to try again. 132 * Next state is normally IDLE. 133 */ 134 if (ioctl(ctx->ct_dev_fd, 135 SMBIOC_IOD_RCFAIL, &vcst) == -1) { 136 err = errno; 137 DPRINT("ioc_rcfail: err %d", err); 138 goto out; 139 } 140 continue; 141 142 case SMBIOD_ST_VCACTIVE: 143 DPRINT("state: active"); 144 if (ioctl(ctx->ct_dev_fd, 145 SMBIOC_IOD_WORK, work) == -1) { 146 err = errno; 147 DPRINT("ioc_work: err %d", err); 148 goto out; 149 } 150 vcst = work->wk_out_state; 151 continue; 152 153 case SMBIOD_ST_DEAD: 154 DPRINT("state: dead"); 155 err = 0; 156 goto out; 157 158 default: 159 DPRINT("state: BAD(%d)", vcst); 160 err = EFAULT; 161 goto out; 162 } 163 } 164 165 out: 166 if (ctx->ct_tran_fd != -1) { 167 close(ctx->ct_tran_fd); 168 ctx->ct_tran_fd = -1; 169 } 170 if (ctx->ct_dev_fd != -1) { 171 close(ctx->ct_dev_fd); 172 ctx->ct_dev_fd = -1; 173 } 174 175 return (err); 176 } 177