1 /*
2  * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef ISTGT_ISCSI_H
29 #define ISTGT_ISCSI_H
30 
31 #include <stdint.h>
32 #include <pthread.h>
33 #include "istgt.h"
34 #include "istgt_iscsi_param.h"
35 #include "istgt_lu.h"
36 #include "istgt_queue.h"
37 
38 #define ISCSI_BHS_LEN 48
39 #define ISCSI_DIGEST_LEN 4
40 #define ISCSI_ALIGNMENT 4
41 /* support version - RFC3720(10.12.4) */
42 #define ISCSI_VERSION 0x00
43 
44 #define ISCSI_ALIGN(SIZE) \
45 	(((SIZE) + (ISCSI_ALIGNMENT - 1)) & ~(ISCSI_ALIGNMENT - 1))
46 
47 #define ISCSI_TEXT_MAX_KEY_LEN 64
48 /* for authentication key (non encoded 1024bytes) RFC3720(5.1/11.1.4) */
49 #define ISCSI_TEXT_MAX_VAL_LEN 8192
50 
51 #define SESS_MTX_LOCK(CONN) \
52 	do {								\
53 		if (pthread_mutex_lock(&(CONN)->sess->mutex) != 0) {	\
54 			ISTGT_ERRLOG("sess lock error\n");		\
55 			pthread_exit(NULL);				\
56 		}							\
57 	} while (0)
58 #define SESS_MTX_UNLOCK(CONN) \
59 	do {								\
60 		if (pthread_mutex_unlock(&(CONN)->sess->mutex) != 0) {	\
61 			ISTGT_ERRLOG("sess unlock error\n");		\
62 			pthread_exit(NULL);				\
63 		}							\
64 	} while (0)
65 
66 typedef enum {
67 	/* Initiator opcodes */
68 	ISCSI_OP_NOPOUT         = 0x00,
69 	ISCSI_OP_SCSI           = 0x01,
70 	ISCSI_OP_TASK           = 0x02,
71 	ISCSI_OP_LOGIN          = 0x03,
72 	ISCSI_OP_TEXT           = 0x04,
73 	ISCSI_OP_SCSI_DATAOUT   = 0x05,
74 	ISCSI_OP_LOGOUT         = 0x06,
75 	ISCSI_OP_SNACK          = 0x10,
76 	ISCSI_OP_VENDOR_1C      = 0x1c,
77 	ISCSI_OP_VENDOR_1D      = 0x1d,
78 	ISCSI_OP_VENDOR_1E      = 0x1e,
79 
80 	/* Target opcodes */
81 	ISCSI_OP_NOPIN          = 0x20,
82 	ISCSI_OP_SCSI_RSP       = 0x21,
83 	ISCSI_OP_TASK_RSP       = 0x22,
84 	ISCSI_OP_LOGIN_RSP      = 0x23,
85 	ISCSI_OP_TEXT_RSP       = 0x24,
86 	ISCSI_OP_SCSI_DATAIN    = 0x25,
87 	ISCSI_OP_LOGOUT_RSP     = 0x26,
88 	ISCSI_OP_R2T            = 0x31,
89 	ISCSI_OP_ASYNC          = 0x32,
90 	ISCSI_OP_VENDOR_3C      = 0x3c,
91 	ISCSI_OP_VENDOR_3D      = 0x3d,
92 	ISCSI_OP_VENDOR_3E      = 0x3e,
93 	ISCSI_OP_REJECT         = 0x3f,
94 } ISCSI_OP;
95 
96 typedef enum {
97 	ISCSI_TASK_FUNC_ABORT_TASK = 1,
98 	ISCSI_TASK_FUNC_ABORT_TASK_SET = 2,
99 	ISCSI_TASK_FUNC_CLEAR_ACA = 3,
100 	ISCSI_TASK_FUNC_CLEAR_TASK_SET = 4,
101 	ISCSI_TASK_FUNC_LOGICAL_UNIT_RESET = 5,
102 	ISCSI_TASK_FUNC_TARGET_WARM_RESET = 6,
103 	ISCSI_TASK_FUNC_TARGET_COLD_RESET = 7,
104 	ISCSI_TASK_FUNC_TASK_REASSIGN = 8,
105 } ISCSI_TASK_FUNC;
106 
107 typedef struct iscsi_bhs_t {
108 	/* 0-3 */
109 	uint8_t opcode;
110 	uint8_t opcode_specific1[3];
111 	/* 4-7 */
112 	uint8_t total_ahs_len;
113 	uint8_t data_segment_len[3];
114 	/* 8-11 */
115 	union {
116 		uint8_t lun1[4];
117 		uint8_t opcode_specific2[4];
118 	} u1;
119 	/* 12-15 */
120 	union {
121 		uint8_t lun2[4];
122 		uint8_t opcode_specific3[4];
123 	} u2;
124 	/* 16-19 */
125 	uint8_t inititator_task_tag[4];
126 	/* 20-47 */
127 	uint8_t opcode_specific4[28];
128 } ISCSI_BHS;
129 
130 typedef struct iscsi_ahs_t {
131 	/* 0-3 */
132 	uint8_t ahs_len[2];
133 	uint8_t ahs_type;
134 	uint8_t ahs_specific1;
135 	/* 4-x */
136 	uint8_t ahs_specific2[];
137 } ISCSI_AHS;
138 
139 typedef struct iscsi_pdu_t {
140 	ISCSI_BHS bhs;
141 	ISCSI_AHS *ahs;
142 	uint8_t header_digest[ISCSI_DIGEST_LEN];
143 	uint8_t shortdata[ISTGT_SHORTDATASIZE];
144 	uint8_t *data;
145 	uint8_t data_digest[ISCSI_DIGEST_LEN];
146 	size_t total_ahs_len;
147 	size_t data_segment_len;
148 	int copy_pdu;
149 } ISCSI_PDU;
150 typedef ISCSI_PDU *ISCSI_PDU_Ptr;
151 
152 typedef enum {
153 	CONN_STATE_INVALID = 0,
154 	CONN_STATE_RUNNING = 1,
155 	CONN_STATE_EXITING = 2,
156 	CONN_STATE_SHUTDOWN = 3,
157 } CONN_STATE;
158 
159 typedef enum {
160 	ISCSI_LOGIN_PHASE_NONE = 0,
161 	ISCSI_LOGIN_PHASE_START = 1,
162 	ISCSI_LOGIN_PHASE_SECURITY = 2,
163 	ISCSI_LOGIN_PHASE_OPERATIONAL = 3,
164 	ISCSI_LOGIN_PHASE_FULLFEATURE = 4,
165 } ISCSI_LOGIN_PHASE;
166 
167 typedef enum {
168 	ISTGT_CHAP_PHASE_NONE = 0,
169 	ISTGT_CHAP_PHASE_WAIT_A = 1,
170 	ISTGT_CHAP_PHASE_WAIT_NR = 2,
171 	ISTGT_CHAP_PHASE_END = 3,
172 } ISTGT_CHAP_PHASE;
173 
174 #define ISTGT_CHAP_CHALLENGE_LEN 1024
175 typedef struct istgt_chap_auth_t {
176 	ISTGT_CHAP_PHASE chap_phase;
177 
178 	char *user;
179 	char *secret;
180 	char *muser;
181 	char *msecret;
182 
183 	uint8_t chap_id[1];
184 	uint8_t chap_mid[1];
185 	int chap_challenge_len;
186 	uint8_t chap_challenge[ISTGT_CHAP_CHALLENGE_LEN];
187 	int chap_mchallenge_len;
188 	uint8_t chap_mchallenge[ISTGT_CHAP_CHALLENGE_LEN];
189 } ISTGT_CHAP_AUTH;
190 
191 typedef struct istgt_r2t_task_t {
192 	struct istgt_conn_t *conn;
193 	ISTGT_LU_Ptr lu;
194 	uint64_t lun;
195 	uint32_t CmdSN;
196 	uint32_t task_tag;
197 	uint32_t transfer_len;
198 	uint32_t transfer_tag;
199 
200 	int iobufsize;
201 	uint8_t *iobuf;
202 
203 	uint32_t R2TSN;
204 	uint32_t DataSN;
205 	int F_bit;
206 	int offset;
207 } ISTGT_R2T_TASK;
208 typedef ISTGT_R2T_TASK *ISTGT_R2T_TASK_Ptr;
209 
210 typedef struct istgt_conn_t {
211 	int id;
212 
213 	ISTGT_Ptr istgt;
214 	PORTAL portal;
215 	int sock;
216 	int wsock;
217 #ifdef ISTGT_USE_KQUEUE
218 	int kq;
219 #endif /* ISTGT_USE_KQUEUE */
220 	int use_sender;
221 	pthread_t thread;
222 	pthread_t sender_thread;
223 	pthread_mutex_t sender_mutex;
224 	pthread_cond_t sender_cond;
225 	struct istgt_sess_t *sess;
226 
227 	CONN_STATE state;
228 	int exec_logout;
229 
230 	int max_pending;
231 	int queue_depth;
232 	pthread_mutex_t wpdu_mutex;
233 	pthread_cond_t wpdu_cond;
234 	ISTGT_QUEUE pending_pdus;
235 	ISCSI_PDU pdu;
236 
237 	int max_r2t;
238 	int pending_r2t;
239 	pthread_mutex_t r2t_mutex;
240 	ISTGT_R2T_TASK_Ptr *r2t_tasks;
241 
242 	int task_pipe[2];
243 	int max_task_queue;
244 	pthread_mutex_t task_queue_mutex;
245 	ISTGT_QUEUE task_queue;
246 	pthread_mutex_t result_queue_mutex;
247 	pthread_cond_t result_queue_cond;
248 	ISTGT_QUEUE result_queue;
249 	ISTGT_LU_TASK_Ptr exec_lu_task;
250 	int running_tasks;
251 
252 	uint16_t cid;
253 
254 	/* IP address */
255 	int initiator_family;
256 	char initiator_addr[MAX_INITIATOR_ADDR];
257 	char target_addr[MAX_TARGET_ADDR];
258 
259 	/* Initiator/Target port binds */
260 	char initiator_name[MAX_INITIATOR_NAME];
261 	char target_name[MAX_TARGET_NAME];
262 	char initiator_port[MAX_INITIATOR_NAME];
263 	char target_port[MAX_TARGET_NAME];
264 
265 	/* for fast access */
266 	int header_digest;
267 	int data_digest;
268 	int full_feature;
269 
270 	ISCSI_PARAM *params;
271 	ISCSI_LOGIN_PHASE login_phase;
272 	ISTGT_CHAP_AUTH auth;
273 	int authenticated;
274 	int req_auth;
275 	int req_mutual;
276 
277 	int timeout;
278 	int nopininterval;
279 
280 	int TargetMaxRecvDataSegmentLength;
281 	int MaxRecvDataSegmentLength;
282 	int MaxOutstandingR2T;
283 	int FirstBurstLength;
284 	int MaxBurstLength;
285 
286 	int shortpdusize;
287 	uint8_t *shortpdu;
288 
289 	int iobufsize;
290 	uint8_t *iobuf;
291 	int snsbufsize;
292 	uint8_t *snsbuf;
293 
294 	int recvbufsize;
295 	int sendbufsize;
296 	uint8_t *recvbuf;
297 	uint8_t *sendbuf;
298 
299 	int worksize;
300 	uint8_t *workbuf;
301 
302 	uint32_t StatSN;
303 } CONN;
304 typedef CONN *CONN_Ptr;
305 
306 typedef struct istgt_sess_t {
307 	int connections;
308 	int max_conns;
309 	CONN_Ptr *conns;
310 
311 	pthread_mutex_t mutex;
312 	pthread_cond_t mcs_cond;
313 	int req_mcs_cond;
314 
315 	char *initiator_port;
316 	char *target_name;
317 	int tag;
318 
319 	uint64_t isid;
320 	uint16_t tsih;
321 	ISTGT_LU_Ptr lu;
322 
323 	ISCSI_PARAM *params;
324 
325 	int MaxConnections;
326 	int MaxOutstandingR2T;
327 	int DefaultTime2Wait;
328 	int DefaultTime2Retain;
329 	int FirstBurstLength;
330 	int MaxBurstLength;
331 	int InitialR2T;
332 	int ImmediateData;
333 	int DataPDUInOrder;
334 	int DataSequenceInOrder;
335 	int ErrorRecoveryLevel;
336 
337 	int initial_r2t;
338 	int immediate_data;
339 
340 	uint32_t ExpCmdSN;
341 	uint32_t MaxCmdSN;
342 } SESS;
343 typedef SESS *SESS_Ptr;
344 
345 #endif /* ISTGT_ISCSI_H */
346