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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
41 #include "isns_server.h"
42 #include "isns_cache.h"
44 #include "isns_msgq.h"
45 #include "isns_func.h"
47 #include "isns_provider.h"
49 /* external functions */
51 extern void dump_pdu1(isns_pdu_t
*);
52 extern int verbose_tc
;
55 extern boolean_t time_to_exit
;
66 isns_pdu_t
*pdu
, *combined_pdu
, *new_combined_pdu
;
70 conn
= (conn_arg_t
*)arg
;
72 conn
->out_packet
.pdu
= NULL
;
73 conn
->out_packet
.sz
= 0;
78 time_to_exit
== B_FALSE
&&
79 isns_rcv_pdu(conn
->so
, &pdu
, &pdu_sz
, ISNS_RCV_TIMEOUT
) > 0) {
80 uint16_t flags
= pdu
->flags
;
81 if (ISNS_MSG_RECEIVED_ENABLED()) {
82 char buf
[INET6_ADDRSTRLEN
];
83 struct sockaddr_storage
*ssp
= &conn
->ss
;
84 struct sockaddr_in
*sinp
= (struct sockaddr_in
*)ssp
;
85 if (ssp
->ss_family
== AF_INET
) {
86 (void) inet_ntop(AF_INET
,
87 (void *)&(sinp
->sin_addr
),
90 (void) inet_ntop(AF_INET6
,
91 (void *)&(sinp
->sin_addr
),
94 ISNS_MSG_RECEIVED((uintptr_t)buf
);
97 if ((flags
& ISNS_FLAG_FIRST_PDU
) == ISNS_FLAG_FIRST_PDU
) {
98 if (combined_pdu
!= NULL
|| pdu
->seq
!= 0) {
104 if (combined_pdu
== NULL
||
105 combined_pdu
->func_id
!= pdu
->func_id
||
106 combined_pdu
->xid
!= pdu
->xid
||
107 (combined_pdu
->seq
+ 1) != pdu
->seq
) {
108 /* expect the first pdu, the same tranx id */
109 /* and the next sequence id */
112 new_combined_pdu
= (isns_pdu_t
*)malloc(
114 combined_pdu
->payload_len
+
116 if (new_combined_pdu
== NULL
) {
119 (void) memcpy((void *)new_combined_pdu
,
120 (void *)combined_pdu
,
121 ISNSP_HEADER_SIZE
+ combined_pdu
->payload_len
);
122 payload_ptr
= new_combined_pdu
->payload
+
123 combined_pdu
->payload_len
;
124 (void) memcpy((void *)payload_ptr
,
125 (void *)pdu
->payload
,
127 new_combined_pdu
->seq
= pdu
->seq
;
129 combined_pdu
= new_combined_pdu
;
133 if ((flags
& ISNS_FLAG_LAST_PDU
) == ISNS_FLAG_LAST_PDU
) {
138 dump_pdu1(combined_pdu
);
140 if (verbose_tc
!= 0) {
146 conn
->in_packet
.pdu
= combined_pdu
;
147 conn
->out_packet
.pl
= 0;
150 if (packet_split_verify(conn
) == 0) {
151 (void) cache_lock(conn
->lock
);
152 status
= conn
->handler(conn
);
153 conn
->ec
= cache_unlock(conn
->lock
, conn
->ec
);
161 status
= isns_response(conn
);
163 isnslog(LOG_DEBUG
, "isns_connection",
164 "Response status: %d.", status
);
165 if (ISNS_MSG_RESPONDED_ENABLED()) {
166 char buf
[INET6_ADDRSTRLEN
];
167 struct sockaddr_storage
*ssp
=
169 struct sockaddr_in
*sinp
=
170 (struct sockaddr_in
*)ssp
;
171 if (ssp
->ss_family
== AF_INET
) {
172 (void) inet_ntop(AF_INET
,
173 (void *)&(sinp
->sin_addr
),
176 (void) inet_ntop(AF_INET6
,
177 (void *)&(sinp
->sin_addr
),
180 ISNS_MSG_RESPONDED((uintptr_t)buf
);
184 /* no need to send response message */
190 if (verbose_tc
!= 0) {
193 printf("time %d clock %.4lf -msg response\n",
194 t
, c
/ (double)CLOCKS_PER_SEC
);
206 if (combined_pdu
!= NULL
) {
209 (void) close(conn
->so
);
210 (void) free(conn
->out_packet
.pdu
);
213 /* decrease the thread ref count */
219 /* the iSNS server port watcher */
223 /* LINTED E_FUNC_ARG_UNUSED */
229 struct sockaddr_in sin
;
230 struct sockaddr_in
*sinp
;
231 struct sockaddr_storage
*ssp
;
233 char buf
[INET6_ADDRSTRLEN
];
240 if ((s
= socket(AF_INET
, SOCK_STREAM
, 0)) != -1) {
242 isnslog(LOG_DEBUG
, "isns_port_watcher", "IPv4 socket created.");
243 (void) setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&opt
,
246 sin
.sin_family
= AF_INET
;
247 sin
.sin_port
= htons(ISNS_DEFAULT_SERVER_PORT
);
248 sin
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
250 if (bind(s
, (struct sockaddr
*)&sin
, sizeof (sin
)) < 0) {
251 isnslog(LOG_DEBUG
, "isns_port_watcher",
252 "binding on server port failed: %%m");
255 isnslog(LOG_DEBUG
, "isns_port_watcher",
256 "successful binding on server port.");
258 isnslog(LOG_DEBUG
, "isns_port_watcher",
259 "cannot create socket: %%m.");
263 if (listen(s
, 5) < 0) {
264 isnslog(LOG_DEBUG
, "isns_port_watcher",
265 "listening on server port failed: %%m.");
268 isnslog(LOG_DEBUG
, "isns_port_watcher", "listening on server port ok.");
271 fds
.events
= (POLLIN
| POLLRDNORM
);
274 /* waiting for connections */
280 poll_ret
= poll(&fds
, 1, 1000);
285 /* allocate a connection argument */
286 conn
= (conn_arg_t
*)malloc(sizeof (conn_arg_t
));
288 isnslog(LOG_DEBUG
, "isns_port_watcher",
293 sslen
= sizeof (conn
->ss
);
294 f
= accept(s
, (struct sockaddr
*)ssp
, &sslen
);
296 isnslog(LOG_DEBUG
, "isns_port_watcher",
297 "accepting connection failed: %%m.");
300 sinp
= (struct sockaddr_in
*)ssp
;
301 if (ssp
->ss_family
== AF_INET
) {
302 (void) inet_ntop(AF_INET
, (void *)&(sinp
->sin_addr
),
305 (void) inet_ntop(AF_INET6
, (void *)&(sinp
->sin_addr
),
308 isnslog(LOG_DEBUG
, "isns_port_watcher",
309 "connection from %s:%d.", buf
,
312 if (ISNS_CONNECTION_ACCEPTED_ENABLED()) {
313 ISNS_CONNECTION_ACCEPTED((uintptr_t)buf
);
317 /* create an isns connection */
318 if (pthread_create(&tid
, NULL
,
319 isns_connection
, (void *)conn
) != 0) {
322 isnslog(LOG_DEBUG
, "isns_port_watcher",
323 "pthread_create() failed.");
325 /* increase the thread ref count */
335 static uint16_t xid
= 0;
336 static pthread_mutex_t xid_mtx
= PTHREAD_MUTEX_INITIALIZER
;
343 (void) pthread_mutex_lock(&xid_mtx
);
345 (void) pthread_mutex_unlock(&xid_mtx
);