xref: /onnv-gate/usr/src/cmd/isns/isnsd/server.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM 
22*7836SJohn.Forte@Sun.COM /*
23*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
25*7836SJohn.Forte@Sun.COM  */
26*7836SJohn.Forte@Sun.COM 
27*7836SJohn.Forte@Sun.COM #include <stdlib.h>
28*7836SJohn.Forte@Sun.COM #include <stdio.h>
29*7836SJohn.Forte@Sun.COM #include <sys/types.h>
30*7836SJohn.Forte@Sun.COM #include <sys/socket.h>
31*7836SJohn.Forte@Sun.COM #include <netinet/in.h>
32*7836SJohn.Forte@Sun.COM #include <arpa/inet.h>
33*7836SJohn.Forte@Sun.COM #include <unistd.h>
34*7836SJohn.Forte@Sun.COM #include <string.h>
35*7836SJohn.Forte@Sun.COM #include <pthread.h>
36*7836SJohn.Forte@Sun.COM #include <poll.h>
37*7836SJohn.Forte@Sun.COM #ifdef DEBUG
38*7836SJohn.Forte@Sun.COM #include <time.h>
39*7836SJohn.Forte@Sun.COM #endif
40*7836SJohn.Forte@Sun.COM 
41*7836SJohn.Forte@Sun.COM #include "isns_server.h"
42*7836SJohn.Forte@Sun.COM #include "isns_cache.h"
43*7836SJohn.Forte@Sun.COM #include "isns_pdu.h"
44*7836SJohn.Forte@Sun.COM #include "isns_msgq.h"
45*7836SJohn.Forte@Sun.COM #include "isns_func.h"
46*7836SJohn.Forte@Sun.COM #include "isns_log.h"
47*7836SJohn.Forte@Sun.COM #include "isns_provider.h"
48*7836SJohn.Forte@Sun.COM 
49*7836SJohn.Forte@Sun.COM /* external functions */
50*7836SJohn.Forte@Sun.COM #ifdef DEBUG
51*7836SJohn.Forte@Sun.COM extern void dump_pdu1(isns_pdu_t *);
52*7836SJohn.Forte@Sun.COM extern int verbose_tc;
53*7836SJohn.Forte@Sun.COM #endif
54*7836SJohn.Forte@Sun.COM 
55*7836SJohn.Forte@Sun.COM extern boolean_t time_to_exit;
56*7836SJohn.Forte@Sun.COM 
57*7836SJohn.Forte@Sun.COM void *
isns_connection(void * arg)58*7836SJohn.Forte@Sun.COM isns_connection(
59*7836SJohn.Forte@Sun.COM 	void *arg
60*7836SJohn.Forte@Sun.COM )
61*7836SJohn.Forte@Sun.COM {
62*7836SJohn.Forte@Sun.COM 	int status = 0;
63*7836SJohn.Forte@Sun.COM 
64*7836SJohn.Forte@Sun.COM 	conn_arg_t *conn;
65*7836SJohn.Forte@Sun.COM 
66*7836SJohn.Forte@Sun.COM 	isns_pdu_t *pdu, *combined_pdu, *new_combined_pdu;
67*7836SJohn.Forte@Sun.COM 	uint8_t *payload_ptr;
68*7836SJohn.Forte@Sun.COM 	size_t pdu_sz;
69*7836SJohn.Forte@Sun.COM 
70*7836SJohn.Forte@Sun.COM 	conn = (conn_arg_t *)arg;
71*7836SJohn.Forte@Sun.COM 
72*7836SJohn.Forte@Sun.COM 	conn->out_packet.pdu = NULL;
73*7836SJohn.Forte@Sun.COM 	conn->out_packet.sz = 0;
74*7836SJohn.Forte@Sun.COM 	combined_pdu = NULL;
75*7836SJohn.Forte@Sun.COM 	pdu = NULL;
76*7836SJohn.Forte@Sun.COM 
77*7836SJohn.Forte@Sun.COM 	while (status == 0 &&
78*7836SJohn.Forte@Sun.COM 	    time_to_exit == B_FALSE &&
79*7836SJohn.Forte@Sun.COM 	    isns_rcv_pdu(conn->so, &pdu, &pdu_sz, ISNS_RCV_TIMEOUT) > 0) {
80*7836SJohn.Forte@Sun.COM 		uint16_t flags = pdu->flags;
81*7836SJohn.Forte@Sun.COM 		if (ISNS_MSG_RECEIVED_ENABLED()) {
82*7836SJohn.Forte@Sun.COM 			char buf[INET6_ADDRSTRLEN];
83*7836SJohn.Forte@Sun.COM 			struct sockaddr_storage *ssp = &conn->ss;
84*7836SJohn.Forte@Sun.COM 			struct sockaddr_in *sinp = (struct sockaddr_in *)ssp;
85*7836SJohn.Forte@Sun.COM 			if (ssp->ss_family == AF_INET) {
86*7836SJohn.Forte@Sun.COM 				(void) inet_ntop(AF_INET,
87*7836SJohn.Forte@Sun.COM 				    (void *)&(sinp->sin_addr),
88*7836SJohn.Forte@Sun.COM 				    buf, sizeof (buf));
89*7836SJohn.Forte@Sun.COM 			} else {
90*7836SJohn.Forte@Sun.COM 				(void) inet_ntop(AF_INET6,
91*7836SJohn.Forte@Sun.COM 				    (void *)&(sinp->sin_addr),
92*7836SJohn.Forte@Sun.COM 				    buf, sizeof (buf));
93*7836SJohn.Forte@Sun.COM 			}
94*7836SJohn.Forte@Sun.COM 			ISNS_MSG_RECEIVED((uintptr_t)buf);
95*7836SJohn.Forte@Sun.COM 		}
96*7836SJohn.Forte@Sun.COM 
97*7836SJohn.Forte@Sun.COM 		if ((flags & ISNS_FLAG_FIRST_PDU) == ISNS_FLAG_FIRST_PDU) {
98*7836SJohn.Forte@Sun.COM 			if (combined_pdu != NULL || pdu->seq != 0) {
99*7836SJohn.Forte@Sun.COM 				goto conn_done;
100*7836SJohn.Forte@Sun.COM 			}
101*7836SJohn.Forte@Sun.COM 			combined_pdu = pdu;
102*7836SJohn.Forte@Sun.COM 			pdu = NULL;
103*7836SJohn.Forte@Sun.COM 		} else {
104*7836SJohn.Forte@Sun.COM 			if (combined_pdu == NULL ||
105*7836SJohn.Forte@Sun.COM 			    combined_pdu->func_id != pdu->func_id ||
106*7836SJohn.Forte@Sun.COM 			    combined_pdu->xid != pdu->xid ||
107*7836SJohn.Forte@Sun.COM 			    (combined_pdu->seq + 1) != pdu->seq) {
108*7836SJohn.Forte@Sun.COM 				/* expect the first pdu, the same tranx id */
109*7836SJohn.Forte@Sun.COM 				/* and the next sequence id */
110*7836SJohn.Forte@Sun.COM 				goto conn_done;
111*7836SJohn.Forte@Sun.COM 			}
112*7836SJohn.Forte@Sun.COM 			new_combined_pdu = (isns_pdu_t *)malloc(
113*7836SJohn.Forte@Sun.COM 			    ISNSP_HEADER_SIZE +
114*7836SJohn.Forte@Sun.COM 			    combined_pdu->payload_len +
115*7836SJohn.Forte@Sun.COM 			    pdu->payload_len);
116*7836SJohn.Forte@Sun.COM 			if (new_combined_pdu == NULL) {
117*7836SJohn.Forte@Sun.COM 				goto conn_done;
118*7836SJohn.Forte@Sun.COM 			}
119*7836SJohn.Forte@Sun.COM 			(void) memcpy((void *)new_combined_pdu,
120*7836SJohn.Forte@Sun.COM 			    (void *)combined_pdu,
121*7836SJohn.Forte@Sun.COM 			    ISNSP_HEADER_SIZE + combined_pdu->payload_len);
122*7836SJohn.Forte@Sun.COM 			payload_ptr = new_combined_pdu->payload +
123*7836SJohn.Forte@Sun.COM 			    combined_pdu->payload_len;
124*7836SJohn.Forte@Sun.COM 			(void) memcpy((void *)payload_ptr,
125*7836SJohn.Forte@Sun.COM 			    (void *)pdu->payload,
126*7836SJohn.Forte@Sun.COM 			    pdu->payload_len);
127*7836SJohn.Forte@Sun.COM 			new_combined_pdu->seq = pdu->seq;
128*7836SJohn.Forte@Sun.COM 			free(combined_pdu);
129*7836SJohn.Forte@Sun.COM 			combined_pdu = new_combined_pdu;
130*7836SJohn.Forte@Sun.COM 			free(pdu);
131*7836SJohn.Forte@Sun.COM 			pdu = NULL;
132*7836SJohn.Forte@Sun.COM 		}
133*7836SJohn.Forte@Sun.COM 		if ((flags & ISNS_FLAG_LAST_PDU) == ISNS_FLAG_LAST_PDU) {
134*7836SJohn.Forte@Sun.COM #ifdef DEBUG
135*7836SJohn.Forte@Sun.COM 			time_t t;
136*7836SJohn.Forte@Sun.COM 			clock_t c;
137*7836SJohn.Forte@Sun.COM 
138*7836SJohn.Forte@Sun.COM 			dump_pdu1(combined_pdu);
139*7836SJohn.Forte@Sun.COM 
140*7836SJohn.Forte@Sun.COM 			if (verbose_tc != 0) {
141*7836SJohn.Forte@Sun.COM 				t = time(NULL);
142*7836SJohn.Forte@Sun.COM 				c = clock();
143*7836SJohn.Forte@Sun.COM 			}
144*7836SJohn.Forte@Sun.COM #endif
145*7836SJohn.Forte@Sun.COM 
146*7836SJohn.Forte@Sun.COM 			conn->in_packet.pdu = combined_pdu;
147*7836SJohn.Forte@Sun.COM 			conn->out_packet.pl = 0;
148*7836SJohn.Forte@Sun.COM 			conn->ec = 0;
149*7836SJohn.Forte@Sun.COM 
150*7836SJohn.Forte@Sun.COM 			if (packet_split_verify(conn) == 0) {
151*7836SJohn.Forte@Sun.COM 				(void) cache_lock(conn->lock);
152*7836SJohn.Forte@Sun.COM 				status = conn->handler(conn);
153*7836SJohn.Forte@Sun.COM 				conn->ec = cache_unlock(conn->lock, conn->ec);
154*7836SJohn.Forte@Sun.COM 			}
155*7836SJohn.Forte@Sun.COM 
156*7836SJohn.Forte@Sun.COM 			switch (status) {
157*7836SJohn.Forte@Sun.COM 			case -1:
158*7836SJohn.Forte@Sun.COM 				/* error */
159*7836SJohn.Forte@Sun.COM 				break;
160*7836SJohn.Forte@Sun.COM 			case 0:
161*7836SJohn.Forte@Sun.COM 				status = isns_response(conn);
162*7836SJohn.Forte@Sun.COM 
163*7836SJohn.Forte@Sun.COM 				isnslog(LOG_DEBUG, "isns_connection",
164*7836SJohn.Forte@Sun.COM 				    "Response status: %d.", status);
165*7836SJohn.Forte@Sun.COM 				if (ISNS_MSG_RESPONDED_ENABLED()) {
166*7836SJohn.Forte@Sun.COM 					char buf[INET6_ADDRSTRLEN];
167*7836SJohn.Forte@Sun.COM 					struct sockaddr_storage *ssp =
168*7836SJohn.Forte@Sun.COM 					    &conn->ss;
169*7836SJohn.Forte@Sun.COM 					struct sockaddr_in *sinp =
170*7836SJohn.Forte@Sun.COM 					    (struct sockaddr_in *)ssp;
171*7836SJohn.Forte@Sun.COM 					if (ssp->ss_family == AF_INET) {
172*7836SJohn.Forte@Sun.COM 						(void) inet_ntop(AF_INET,
173*7836SJohn.Forte@Sun.COM 						    (void *)&(sinp->sin_addr),
174*7836SJohn.Forte@Sun.COM 						    buf, sizeof (buf));
175*7836SJohn.Forte@Sun.COM 					} else {
176*7836SJohn.Forte@Sun.COM 						(void) inet_ntop(AF_INET6,
177*7836SJohn.Forte@Sun.COM 						    (void *)&(sinp->sin_addr),
178*7836SJohn.Forte@Sun.COM 						    buf, sizeof (buf));
179*7836SJohn.Forte@Sun.COM 					}
180*7836SJohn.Forte@Sun.COM 					ISNS_MSG_RESPONDED((uintptr_t)buf);
181*7836SJohn.Forte@Sun.COM 				}
182*7836SJohn.Forte@Sun.COM 				break;
183*7836SJohn.Forte@Sun.COM 			default:
184*7836SJohn.Forte@Sun.COM 				/* no need to send response message */
185*7836SJohn.Forte@Sun.COM 				status = 0;
186*7836SJohn.Forte@Sun.COM 				break;
187*7836SJohn.Forte@Sun.COM 			}
188*7836SJohn.Forte@Sun.COM 
189*7836SJohn.Forte@Sun.COM #ifdef DEBUG
190*7836SJohn.Forte@Sun.COM 			if (verbose_tc != 0) {
191*7836SJohn.Forte@Sun.COM 				t = time(NULL) - t;
192*7836SJohn.Forte@Sun.COM 				c = clock() - c;
193*7836SJohn.Forte@Sun.COM 				printf("time %d clock %.4lf -msg response\n",
194*7836SJohn.Forte@Sun.COM 				    t, c / (double)CLOCKS_PER_SEC);
195*7836SJohn.Forte@Sun.COM 			}
196*7836SJohn.Forte@Sun.COM #endif
197*7836SJohn.Forte@Sun.COM 			free(combined_pdu);
198*7836SJohn.Forte@Sun.COM 			combined_pdu = NULL;
199*7836SJohn.Forte@Sun.COM 		}
200*7836SJohn.Forte@Sun.COM 	}
201*7836SJohn.Forte@Sun.COM 
202*7836SJohn.Forte@Sun.COM conn_done:
203*7836SJohn.Forte@Sun.COM 	if (pdu != NULL) {
204*7836SJohn.Forte@Sun.COM 		free(pdu);
205*7836SJohn.Forte@Sun.COM 	}
206*7836SJohn.Forte@Sun.COM 	if (combined_pdu != NULL) {
207*7836SJohn.Forte@Sun.COM 		free(combined_pdu);
208*7836SJohn.Forte@Sun.COM 	}
209*7836SJohn.Forte@Sun.COM 	(void) close(conn->so);
210*7836SJohn.Forte@Sun.COM 	(void) free(conn->out_packet.pdu);
211*7836SJohn.Forte@Sun.COM 	(void) free(conn);
212*7836SJohn.Forte@Sun.COM 
213*7836SJohn.Forte@Sun.COM 	/* decrease the thread ref count */
214*7836SJohn.Forte@Sun.COM 	dec_thr_count();
215*7836SJohn.Forte@Sun.COM 
216*7836SJohn.Forte@Sun.COM 	return (NULL);
217*7836SJohn.Forte@Sun.COM }
218*7836SJohn.Forte@Sun.COM 
219*7836SJohn.Forte@Sun.COM /* the iSNS server port watcher */
220*7836SJohn.Forte@Sun.COM 
221*7836SJohn.Forte@Sun.COM void *
isns_port_watcher(void * arg)222*7836SJohn.Forte@Sun.COM isns_port_watcher(
223*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
224*7836SJohn.Forte@Sun.COM 	void *arg
225*7836SJohn.Forte@Sun.COM )
226*7836SJohn.Forte@Sun.COM {
227*7836SJohn.Forte@Sun.COM 	int s, f;
228*7836SJohn.Forte@Sun.COM 	int opt = 1;
229*7836SJohn.Forte@Sun.COM 	struct sockaddr_in sin;
230*7836SJohn.Forte@Sun.COM 	struct sockaddr_in *sinp;
231*7836SJohn.Forte@Sun.COM 	struct sockaddr_storage *ssp;
232*7836SJohn.Forte@Sun.COM 	socklen_t sslen;
233*7836SJohn.Forte@Sun.COM 	char buf[INET6_ADDRSTRLEN];
234*7836SJohn.Forte@Sun.COM 	pthread_t tid;
235*7836SJohn.Forte@Sun.COM 	struct pollfd fds;
236*7836SJohn.Forte@Sun.COM 	int poll_ret;
237*7836SJohn.Forte@Sun.COM 
238*7836SJohn.Forte@Sun.COM 	conn_arg_t *conn;
239*7836SJohn.Forte@Sun.COM 
240*7836SJohn.Forte@Sun.COM 	if ((s = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
241*7836SJohn.Forte@Sun.COM 		/* IPv4 */
242*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "isns_port_watcher", "IPv4 socket created.");
243*7836SJohn.Forte@Sun.COM 		(void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&opt,
244*7836SJohn.Forte@Sun.COM 		    sizeof (opt));
245*7836SJohn.Forte@Sun.COM 
246*7836SJohn.Forte@Sun.COM 		sin.sin_family		= AF_INET;
247*7836SJohn.Forte@Sun.COM 		sin.sin_port		= htons(ISNS_DEFAULT_SERVER_PORT);
248*7836SJohn.Forte@Sun.COM 		sin.sin_addr.s_addr	= htonl(INADDR_ANY);
249*7836SJohn.Forte@Sun.COM 
250*7836SJohn.Forte@Sun.COM 		if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
251*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "isns_port_watcher",
252*7836SJohn.Forte@Sun.COM 			    "binding on server port failed: %%m");
253*7836SJohn.Forte@Sun.COM 			goto watch_failed;
254*7836SJohn.Forte@Sun.COM 		}
255*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "isns_port_watcher",
256*7836SJohn.Forte@Sun.COM 		    "successful binding on server port.");
257*7836SJohn.Forte@Sun.COM 	} else {
258*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "isns_port_watcher",
259*7836SJohn.Forte@Sun.COM 		    "cannot create socket: %%m.");
260*7836SJohn.Forte@Sun.COM 		goto watch_failed;
261*7836SJohn.Forte@Sun.COM 	}
262*7836SJohn.Forte@Sun.COM 
263*7836SJohn.Forte@Sun.COM 	if (listen(s, 5) < 0) {
264*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "isns_port_watcher",
265*7836SJohn.Forte@Sun.COM 		    "listening on server port failed: %%m.");
266*7836SJohn.Forte@Sun.COM 		goto watch_failed;
267*7836SJohn.Forte@Sun.COM 	}
268*7836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "isns_port_watcher", "listening on server port ok.");
269*7836SJohn.Forte@Sun.COM 
270*7836SJohn.Forte@Sun.COM 	fds.fd = s;
271*7836SJohn.Forte@Sun.COM 	fds.events = (POLLIN | POLLRDNORM);
272*7836SJohn.Forte@Sun.COM 	fds.revents = 0;
273*7836SJohn.Forte@Sun.COM 
274*7836SJohn.Forte@Sun.COM 	/* waiting for connections */
275*7836SJohn.Forte@Sun.COM 	for (;;) {
276*7836SJohn.Forte@Sun.COM 		if (time_to_exit) {
277*7836SJohn.Forte@Sun.COM 			return (NULL);
278*7836SJohn.Forte@Sun.COM 		}
279*7836SJohn.Forte@Sun.COM 
280*7836SJohn.Forte@Sun.COM 		poll_ret = poll(&fds, 1, 1000);
281*7836SJohn.Forte@Sun.COM 		if (poll_ret <= 0) {
282*7836SJohn.Forte@Sun.COM 			continue;
283*7836SJohn.Forte@Sun.COM 		}
284*7836SJohn.Forte@Sun.COM 
285*7836SJohn.Forte@Sun.COM 		/* allocate a connection argument */
286*7836SJohn.Forte@Sun.COM 		conn = (conn_arg_t *)malloc(sizeof (conn_arg_t));
287*7836SJohn.Forte@Sun.COM 		if (conn == NULL) {
288*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "isns_port_watcher",
289*7836SJohn.Forte@Sun.COM 			    "malloc() failed.");
290*7836SJohn.Forte@Sun.COM 			goto watch_failed;
291*7836SJohn.Forte@Sun.COM 		}
292*7836SJohn.Forte@Sun.COM 		ssp = &conn->ss;
293*7836SJohn.Forte@Sun.COM 		sslen = sizeof (conn->ss);
294*7836SJohn.Forte@Sun.COM 		f = accept(s, (struct sockaddr *)ssp, &sslen);
295*7836SJohn.Forte@Sun.COM 		if (f < 0) {
296*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "isns_port_watcher",
297*7836SJohn.Forte@Sun.COM 			    "accepting connection failed: %%m.");
298*7836SJohn.Forte@Sun.COM 			goto watch_failed;
299*7836SJohn.Forte@Sun.COM 		}
300*7836SJohn.Forte@Sun.COM 		sinp = (struct sockaddr_in *)ssp;
301*7836SJohn.Forte@Sun.COM 		if (ssp->ss_family == AF_INET) {
302*7836SJohn.Forte@Sun.COM 			(void) inet_ntop(AF_INET, (void *)&(sinp->sin_addr),
303*7836SJohn.Forte@Sun.COM 			    buf, sizeof (buf));
304*7836SJohn.Forte@Sun.COM 		} else {
305*7836SJohn.Forte@Sun.COM 			(void) inet_ntop(AF_INET6, (void *)&(sinp->sin_addr),
306*7836SJohn.Forte@Sun.COM 			    buf, sizeof (buf));
307*7836SJohn.Forte@Sun.COM 		}
308*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "isns_port_watcher",
309*7836SJohn.Forte@Sun.COM 		    "connection from %s:%d.", buf,
310*7836SJohn.Forte@Sun.COM 		    sinp->sin_port);
311*7836SJohn.Forte@Sun.COM 
312*7836SJohn.Forte@Sun.COM 		if (ISNS_CONNECTION_ACCEPTED_ENABLED()) {
313*7836SJohn.Forte@Sun.COM 			ISNS_CONNECTION_ACCEPTED((uintptr_t)buf);
314*7836SJohn.Forte@Sun.COM 		}
315*7836SJohn.Forte@Sun.COM 
316*7836SJohn.Forte@Sun.COM 		conn->so = f;
317*7836SJohn.Forte@Sun.COM 		/* create an isns connection */
318*7836SJohn.Forte@Sun.COM 		if (pthread_create(&tid, NULL,
319*7836SJohn.Forte@Sun.COM 		    isns_connection, (void *)conn) != 0) {
320*7836SJohn.Forte@Sun.COM 			(void) close(f);
321*7836SJohn.Forte@Sun.COM 			(void) free(conn);
322*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "isns_port_watcher",
323*7836SJohn.Forte@Sun.COM 			    "pthread_create() failed.");
324*7836SJohn.Forte@Sun.COM 		} else {
325*7836SJohn.Forte@Sun.COM 			/* increase the thread ref count */
326*7836SJohn.Forte@Sun.COM 			inc_thr_count();
327*7836SJohn.Forte@Sun.COM 		}
328*7836SJohn.Forte@Sun.COM 	}
329*7836SJohn.Forte@Sun.COM 
330*7836SJohn.Forte@Sun.COM watch_failed:
331*7836SJohn.Forte@Sun.COM 	shutdown_server();
332*7836SJohn.Forte@Sun.COM 	return (NULL);
333*7836SJohn.Forte@Sun.COM }
334*7836SJohn.Forte@Sun.COM 
335*7836SJohn.Forte@Sun.COM static uint16_t xid = 0;
336*7836SJohn.Forte@Sun.COM static pthread_mutex_t xid_mtx = PTHREAD_MUTEX_INITIALIZER;
337*7836SJohn.Forte@Sun.COM uint16_t
get_server_xid()338*7836SJohn.Forte@Sun.COM get_server_xid(
339*7836SJohn.Forte@Sun.COM )
340*7836SJohn.Forte@Sun.COM {
341*7836SJohn.Forte@Sun.COM 	uint16_t tmp;
342*7836SJohn.Forte@Sun.COM 
343*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&xid_mtx);
344*7836SJohn.Forte@Sun.COM 	tmp = ++ xid;
345*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&xid_mtx);
346*7836SJohn.Forte@Sun.COM 
347*7836SJohn.Forte@Sun.COM 	return (tmp);
348*7836SJohn.Forte@Sun.COM }
349