annotate usr/src/cmd/fm/modules/common/ip-transport/ip.c @ 0:c9caec207d52 b86

Initial porting based on b86
author Koji Uno <koji.uno@sun.com>
date Tue, 02 Jun 2009 18:56:50 +0900
parents
children 1a15d5aaf794
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
1 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
2 * CDDL HEADER START
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
3 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
4 * The contents of this file are subject to the terms of the
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
5 * Common Development and Distribution License (the "License").
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
6 * You may not use this file except in compliance with the License.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
7 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
9 * or http://www.opensolaris.org/os/licensing.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
10 * See the License for the specific language governing permissions
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
11 * and limitations under the License.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
12 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
13 * When distributing Covered Code, include this CDDL HEADER in each
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
15 * If applicable, add the following below this CDDL HEADER, with the
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
16 * fields enclosed by brackets "[]" replaced with your own identifying
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
17 * information: Portions Copyright [yyyy] [name of copyright owner]
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
18 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
19 * CDDL HEADER END
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
20 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
21
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
22 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
24 * Use is subject to license terms.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
25 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
26
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
27 #pragma ident "@(#)ip.c 1.2 06/03/08 SMI"
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
28
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
29 #include <sys/types.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
30 #include <sys/socket.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
31 #include <sys/sysmacros.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
32 #include <sys/fm/protocol.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
33
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
34 #include <netinet/in.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
35 #include <arpa/inet.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
36
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
37 #include <strings.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
38 #include <unistd.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
39 #include <pthread.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
40 #include <alloca.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
41 #include <fcntl.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
42 #include <errno.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
43 #include <netdb.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
44 #include <poll.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
45
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
46 #include <fm/fmd_api.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
47
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
48 #define IP_MAGIC "\177FMA" /* magic string identifying a packet header */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
49 #define IP_MAGLEN 4 /* length of magic string */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
50
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
51 typedef struct ip_hdr {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
52 char iph_magic[IP_MAGLEN]; /* magic string */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
53 uint32_t iph_size; /* packed size */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
54 } ip_hdr_t;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
55
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
56 typedef struct ip_buf {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
57 void *ipb_buf; /* data buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
58 size_t ipb_size; /* size of buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
59 } ip_buf_t;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
60
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
61 typedef struct ip_xprt {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
62 fmd_xprt_t *ipx_xprt; /* transport handle */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
63 int ipx_flags; /* transport flags */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
64 int ipx_fd; /* socket file descriptor */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
65 int ipx_done; /* flag indicating connection closed */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
66 pthread_t ipx_tid; /* recv-side auxiliary thread */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
67 ip_buf_t ipx_sndbuf; /* buffer for sending events */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
68 ip_buf_t ipx_rcvbuf; /* buffer for receiving events */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
69 struct ip_xprt *ipx_next; /* next ip_xprt in global list */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
70 } ip_xprt_t;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
71
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
72 typedef struct ip_stat {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
73 fmd_stat_t ips_accfail; /* failed accepts */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
74 fmd_stat_t ips_badmagic; /* invalid packet headers */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
75 fmd_stat_t ips_packfail; /* failed packs */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
76 fmd_stat_t ips_unpackfail; /* failed unpacks */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
77 } ip_stat_t;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
78
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
79 static void ip_xprt_create(fmd_xprt_t *, int, int);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
80 static void ip_xprt_destroy(ip_xprt_t *);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
81
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
82 static ip_stat_t ip_stat = {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
83 { "accfail", FMD_TYPE_UINT64, "failed accepts" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
84 { "badmagic", FMD_TYPE_UINT64, "invalid packet headers" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
85 { "packfail", FMD_TYPE_UINT64, "failed packs" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
86 { "unpackfail", FMD_TYPE_UINT64, "failed unpacks" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
87 };
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
88
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
89 static fmd_hdl_t *ip_hdl; /* module handle */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
90 static pthread_mutex_t ip_lock; /* lock for ip_xps list */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
91 static ip_xprt_t *ip_xps; /* list of active transports */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
92 static nvlist_t *ip_auth; /* authority to use for transport(s) */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
93 static size_t ip_size; /* default buffer size */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
94 static volatile int ip_quit; /* signal to quit */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
95 static int ip_qlen; /* queue length for listen(3SOCKET) */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
96 static int ip_mtbf; /* mtbf for simulating packet drop */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
97 static hrtime_t ip_burp; /* make mtbf slower by adding this much delay */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
98 static int ip_translate; /* call fmd_xprt_translate() before sending */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
99 static char *ip_host; /* host to connect to (or NULL if server) */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
100 static char *ip_port; /* port to connect to (or bind to if server) */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
101 static struct addrinfo *ip_ail; /* addr info list for ip_host/ip_port */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
102 static uint_t ip_retry; /* retry count for ip_xprt_setup() */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
103 static hrtime_t ip_sleep; /* sleep delay for ip_xprt_setup() */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
104
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
105 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
106 * Allocate space in ipx_sndbuf for a header and a packed XDR encoding of
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
107 * the specified nvlist, and then send the buffer to our remote peer.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
108 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
109 /*ARGSUSED*/
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
110 static int
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
111 ip_xprt_send(fmd_hdl_t *hdl, fmd_xprt_t *xp, fmd_event_t *ep, nvlist_t *nvl)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
112 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
113 ip_xprt_t *ipx = fmd_xprt_getspecific(hdl, xp);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
114
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
115 size_t size, nvsize;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
116 char *buf, *nvbuf;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
117 ip_hdr_t *iph;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
118 ssize_t r, n;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
119 int err;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
120
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
121 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
122 * For testing purposes, if ip_mtbf is non-zero, use this to pseudo-
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
123 * randomly simulate the need for retries. If ip_burp is also set,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
124 * then we also suspend the transport for a bit and wake it up again.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
125 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
126 if (ip_mtbf != 0 && gethrtime() % ip_mtbf == 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
127 if (ip_burp != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
128 fmd_hdl_debug(ip_hdl, "burping ipx %p", (void *)ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
129 ipx->ipx_flags |= FMD_XPRT_SUSPENDED;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
130 (void) fmd_timer_install(ip_hdl, ipx, NULL, ip_burp);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
131 fmd_xprt_suspend(ip_hdl, xp);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
132 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
133 return (FMD_SEND_RETRY);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
134 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
135
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
136 if (ip_translate && (nvl = fmd_xprt_translate(hdl, xp, ep)) == NULL) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
137 fmd_hdl_error(hdl, "failed to translate event %p", (void *)ep);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
138 return (FMD_SEND_FAILED);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
139 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
140
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
141 (void) nvlist_size(nvl, &nvsize, NV_ENCODE_XDR);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
142 size = r = sizeof (ip_hdr_t) + nvsize;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
143
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
144 if (ipx->ipx_sndbuf.ipb_size < size) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
145 fmd_hdl_free(hdl, ipx->ipx_sndbuf.ipb_buf,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
146 ipx->ipx_sndbuf.ipb_size);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
147 ipx->ipx_sndbuf.ipb_size = P2ROUNDUP(size, 16);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
148 ipx->ipx_sndbuf.ipb_buf = fmd_hdl_alloc(hdl,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
149 ipx->ipx_sndbuf.ipb_size, FMD_SLEEP);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
150 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
151
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
152 buf = ipx->ipx_sndbuf.ipb_buf;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
153 iph = (ip_hdr_t *)(uintptr_t)buf;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
154 nvbuf = buf + sizeof (ip_hdr_t);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
155
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
156 bcopy(IP_MAGIC, iph->iph_magic, IP_MAGLEN);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
157 iph->iph_size = htonl(nvsize);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
158 err = nvlist_pack(nvl, &nvbuf, &nvsize, NV_ENCODE_XDR, 0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
159
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
160 if (ip_translate)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
161 nvlist_free(nvl);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
162
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
163 if (err != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
164 fmd_hdl_error(ip_hdl, "failed to pack event for "
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
165 "transport %p: %s\n", (void *)ipx->ipx_xprt, strerror(err));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
166 ip_stat.ips_packfail.fmds_value.ui64++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
167 return (FMD_SEND_FAILED);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
168 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
169
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
170 while (!ip_quit && r != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
171 if ((n = send(ipx->ipx_fd, buf, r, 0)) < 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
172 if (errno != EINTR && errno != EWOULDBLOCK) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
173 fmd_hdl_debug(ip_hdl,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
174 "failed to send on ipx %p", (void *)ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
175 return (FMD_SEND_FAILED);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
176 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
177 continue;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
178 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
179 buf += n;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
180 r -= n;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
181 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
182
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
183 return (FMD_SEND_SUCCESS);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
184 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
185
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
186 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
187 * Receive a chunk of data of the specified size from our remote peer. The
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
188 * data is received into ipx_rcvbuf, and then a pointer to the buffer is
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
189 * returned. NOTE: The data is only valid until the next call to ip_xprt_recv.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
190 * If the connection breaks or ip_quit is set during receive, NULL is returned.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
191 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
192 static void *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
193 ip_xprt_recv(ip_xprt_t *ipx, size_t size)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
194 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
195 char *buf = ipx->ipx_rcvbuf.ipb_buf;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
196 ssize_t n, r = size;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
197
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
198 if (ipx->ipx_rcvbuf.ipb_size < size) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
199 fmd_hdl_free(ip_hdl, ipx->ipx_rcvbuf.ipb_buf,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
200 ipx->ipx_rcvbuf.ipb_size);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
201 ipx->ipx_rcvbuf.ipb_size = P2ROUNDUP(size, 16);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
202 ipx->ipx_rcvbuf.ipb_buf = buf = fmd_hdl_alloc(ip_hdl,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
203 ipx->ipx_rcvbuf.ipb_size, FMD_SLEEP);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
204 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
205
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
206 while (!ip_quit && r != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
207 if ((n = recv(ipx->ipx_fd, buf, r, MSG_WAITALL)) == 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
208 ipx->ipx_done++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
209 return (NULL);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
210 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
211
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
212 if (n < 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
213 if (errno != EINTR && errno != EWOULDBLOCK) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
214 fmd_hdl_debug(ip_hdl,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
215 "failed to recv on ipx %p", (void *)ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
216 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
217 continue;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
218 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
219
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
220 buf += n;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
221 r -= n;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
222 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
223
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
224 return (r ? NULL: ipx->ipx_rcvbuf.ipb_buf);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
225 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
226
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
227 static nvlist_t *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
228 ip_xprt_auth(const struct sockaddr *sap)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
229 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
230 const struct sockaddr_in6 *sin6 = (const void *)sap;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
231 const struct sockaddr_in *sin = (const void *)sap;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
232
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
233 char buf[INET6_ADDRSTRLEN + 16];
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
234 struct in_addr v4addr;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
235 in_port_t port;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
236
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
237 nvlist_t *nvl;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
238 size_t n;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
239 int err;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
240
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
241 if (ip_auth != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
242 err = nvlist_dup(ip_auth, &nvl, 0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
243 else
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
244 err = nvlist_alloc(&nvl, 0, 0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
245
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
246 if (err != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
247 fmd_hdl_abort(ip_hdl, "failed to create nvlist for "
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
248 "authority: %s\n", strerror(err));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
249 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
250
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
251 if (ip_auth != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
252 return (nvl);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
253
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
254 if (sap->sa_family == AF_INET6 &&
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
255 IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
256 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, &v4addr);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
257 (void) inet_ntop(AF_INET, &v4addr, buf, sizeof (buf));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
258 port = ntohs(sin6->sin6_port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
259 } else if (sap->sa_family == AF_INET6) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
260 (void) inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof (buf));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
261 port = ntohs(sin6->sin6_port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
262 } else {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
263 (void) inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof (buf));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
264 port = ntohs(sin->sin_port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
265 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
266
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
267 n = strlen(buf);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
268 (void) snprintf(buf + n, sizeof (buf) - n, ":%u", port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
269 fmd_hdl_debug(ip_hdl, "ip_authority %s=%s\n", FM_FMRI_AUTH_SERVER, buf);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
270
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
271 (void) nvlist_add_uint8(nvl, FM_VERSION, FM_FMRI_AUTH_VERSION);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
272 (void) nvlist_add_string(nvl, FM_FMRI_AUTH_SERVER, buf);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
273
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
274 return (nvl);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
275 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
276
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
277 static void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
278 ip_xprt_accept(ip_xprt_t *ipx)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
279 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
280 struct sockaddr_storage sa;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
281 socklen_t salen = sizeof (sa);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
282 fmd_xprt_t *xp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
283 int fd;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
284
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
285 if ((fd = accept(ipx->ipx_fd, (struct sockaddr *)&sa, &salen)) == -1) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
286 fmd_hdl_error(ip_hdl, "failed to accept connection");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
287 ip_stat.ips_accfail.fmds_value.ui64++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
288 return;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
289 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
290
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
291 xp = fmd_xprt_open(ip_hdl, ipx->ipx_flags,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
292 ip_xprt_auth((struct sockaddr *)&sa), NULL);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
293 ip_xprt_create(xp, fd, ipx->ipx_flags);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
294 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
295
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
296 static void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
297 ip_xprt_recv_event(ip_xprt_t *ipx)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
298 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
299 ip_hdr_t *iph;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
300 nvlist_t *nvl;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
301 size_t size;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
302 void *buf;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
303 int err;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
304
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
305 if ((iph = ip_xprt_recv(ipx, sizeof (ip_hdr_t))) == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
306 return; /* connection broken */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
307
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
308 if (bcmp(iph->iph_magic, IP_MAGIC, IP_MAGLEN) != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
309 fmd_hdl_error(ip_hdl,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
310 "invalid hdr magic %x.%x.%x.%x from transport %p\n",
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
311 iph->iph_magic[0], iph->iph_magic[1], iph->iph_magic[2],
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
312 iph->iph_magic[3], (void *)ipx->ipx_xprt);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
313 ip_stat.ips_badmagic.fmds_value.ui64++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
314 return;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
315 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
316
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
317 size = ntohl(iph->iph_size);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
318
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
319 if ((buf = ip_xprt_recv(ipx, size)) == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
320 return; /* connection broken */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
321
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
322 if ((err = nvlist_unpack(buf, size, &nvl, 0)) != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
323 fmd_hdl_error(ip_hdl, "failed to unpack event from "
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
324 "transport %p: %s\n", (void *)ipx->ipx_xprt, strerror(err));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
325 ip_stat.ips_unpackfail.fmds_value.ui64++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
326 } else
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
327 fmd_xprt_post(ip_hdl, ipx->ipx_xprt, nvl, 0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
328
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
329 if (fmd_xprt_error(ip_hdl, ipx->ipx_xprt)) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
330 fmd_hdl_error(ip_hdl, "protocol error on transport %p",
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
331 (void *)ipx->ipx_xprt);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
332 ipx->ipx_done++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
333 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
334 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
335
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
336 static void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
337 ip_xprt_thread(void *arg)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
338 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
339 ip_xprt_t *ipx = arg;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
340 struct sockaddr_storage sa;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
341 socklen_t salen = sizeof (sa);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
342 struct pollfd pfd;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
343 id_t id;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
344
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
345 while (!ip_quit && !ipx->ipx_done) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
346 if (ipx->ipx_xprt != NULL || (ipx->ipx_flags & FMD_XPRT_ACCEPT))
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
347 pfd.events = POLLIN;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
348 else
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
349 pfd.events = POLLOUT;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
350
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
351 pfd.fd = ipx->ipx_fd;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
352 pfd.revents = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
353
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
354 if (poll(&pfd, 1, -1) <= 0)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
355 continue; /* loop around and check ip_quit */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
356
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
357 if (pfd.revents & (POLLHUP | POLLERR)) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
358 fmd_hdl_debug(ip_hdl, "hangup fd %d\n", ipx->ipx_fd);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
359 break;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
360 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
361
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
362 if (pfd.revents & POLLOUT) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
363 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
364 * Once we're connected, there's no reason to have our
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
365 * calls to recv() and send() be non-blocking since we
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
366 * we have separate threads for each: clear O_NONBLOCK.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
367 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
368 (void) fcntl(ipx->ipx_fd, F_SETFL,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
369 fcntl(ipx->ipx_fd, F_GETFL, 0) & ~O_NONBLOCK);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
370
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
371 if (getpeername(ipx->ipx_fd, (struct sockaddr *)&sa,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
372 &salen) != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
373 fmd_hdl_error(ip_hdl, "failed to get peer name "
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
374 "for fd %d", ipx->ipx_fd);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
375 bzero(&sa, sizeof (sa));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
376 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
377
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
378 ipx->ipx_xprt = fmd_xprt_open(ip_hdl, ipx->ipx_flags,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
379 ip_xprt_auth((struct sockaddr *)&sa), ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
380
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
381 fmd_hdl_debug(ip_hdl, "connect fd %d\n", ipx->ipx_fd);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
382 continue;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
383 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
384
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
385 if (pfd.revents & POLLIN) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
386 if (ipx->ipx_xprt == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
387 ip_xprt_accept(ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
388 else
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
389 ip_xprt_recv_event(ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
390 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
391 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
392
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
393 id = fmd_timer_install(ip_hdl, ipx, NULL, 0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
394 fmd_hdl_debug(ip_hdl, "close fd %d (timer %d)\n", ipx->ipx_fd, (int)id);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
395 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
396
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
397 static void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
398 ip_xprt_create(fmd_xprt_t *xp, int fd, int flags)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
399 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
400 ip_xprt_t *ipx = fmd_hdl_zalloc(ip_hdl, sizeof (ip_xprt_t), FMD_SLEEP);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
401
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
402 ipx->ipx_xprt = xp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
403 ipx->ipx_flags = flags;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
404 ipx->ipx_fd = fd;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
405 ipx->ipx_tid = fmd_thr_create(ip_hdl, ip_xprt_thread, ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
406
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
407 if (ipx->ipx_xprt != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
408 fmd_xprt_setspecific(ip_hdl, ipx->ipx_xprt, ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
409
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
410 (void) pthread_mutex_lock(&ip_lock);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
411
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
412 ipx->ipx_next = ip_xps;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
413 ip_xps = ipx;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
414
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
415 (void) pthread_mutex_unlock(&ip_lock);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
416 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
417
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
418 static void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
419 ip_xprt_destroy(ip_xprt_t *ipx)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
420 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
421 ip_xprt_t *ipp, **ppx = &ip_xps;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
422
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
423 (void) pthread_mutex_lock(&ip_lock);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
424
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
425 for (ipp = *ppx; ipp != NULL; ipp = ipp->ipx_next) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
426 if (ipp != ipx)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
427 ppx = &ipp->ipx_next;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
428 else
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
429 break;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
430 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
431
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
432 if (ipp != ipx) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
433 (void) pthread_mutex_unlock(&ip_lock);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
434 fmd_hdl_abort(ip_hdl, "ipx %p not on xps list\n", (void *)ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
435 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
436
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
437 *ppx = ipx->ipx_next;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
438 ipx->ipx_next = NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
439
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
440 (void) pthread_mutex_unlock(&ip_lock);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
441
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
442 fmd_thr_signal(ip_hdl, ipx->ipx_tid);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
443 fmd_thr_destroy(ip_hdl, ipx->ipx_tid);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
444
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
445 if (ipx->ipx_xprt != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
446 fmd_xprt_close(ip_hdl, ipx->ipx_xprt);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
447
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
448 fmd_hdl_free(ip_hdl, ipx->ipx_sndbuf.ipb_buf, ipx->ipx_sndbuf.ipb_size);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
449 fmd_hdl_free(ip_hdl, ipx->ipx_rcvbuf.ipb_buf, ipx->ipx_rcvbuf.ipb_size);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
450
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
451 (void) close(ipx->ipx_fd);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
452 fmd_hdl_free(ip_hdl, ipx, sizeof (ip_xprt_t));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
453 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
454
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
455 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
456 * Loop through the addresses that were returned by getaddrinfo() in _fmd_init
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
457 * and for each one attempt to create a socket and initialize it. If we are
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
458 * successful, return zero. If we fail, we check ip_retry: if it is non-zero
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
459 * we return the last errno and let our caller retry ip_xprt_setup() later. If
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
460 * ip_retry reaches zero, we call fmd_hdl_abort() with an appropriate message.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
461 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
462 static int
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
463 ip_xprt_setup(fmd_hdl_t *hdl)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
464 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
465 int err, fd, oflags, xflags, optval = 1;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
466 struct addrinfo *aip;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
467 const char *s1, *s2;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
468
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
469 if (ip_host != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
470 xflags = FMD_XPRT_RDWR;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
471 else
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
472 xflags = FMD_XPRT_RDWR | FMD_XPRT_ACCEPT;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
473
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
474 for (aip = ip_ail; aip != NULL; aip = aip->ai_next) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
475 if (aip->ai_family != AF_INET && aip->ai_family != AF_INET6)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
476 continue; /* ignore anything that isn't IPv4 or IPv6 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
477
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
478 if ((fd = socket(aip->ai_family,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
479 aip->ai_socktype, aip->ai_protocol)) == -1) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
480 err = errno;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
481 continue;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
482 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
483
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
484 oflags = fcntl(fd, F_GETFL, 0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
485 (void) fcntl(fd, F_SETFL, oflags | O_NONBLOCK);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
486
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
487 if (xflags & FMD_XPRT_ACCEPT) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
488 err = setsockopt(fd, SOL_SOCKET,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
489 SO_REUSEADDR, &optval, sizeof (optval)) != 0 ||
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
490 bind(fd, aip->ai_addr, aip->ai_addrlen) != 0 ||
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
491 listen(fd, ip_qlen) != 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
492 } else {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
493 err = connect(fd, aip->ai_addr,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
494 aip->ai_addrlen) != 0 && errno != EINPROGRESS;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
495 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
496
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
497 if (err == 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
498 ip_xprt_create(NULL, fd, xflags);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
499 freeaddrinfo(ip_ail);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
500 ip_ail = NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
501 return (0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
502 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
503
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
504 err = errno;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
505 (void) close(fd);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
506 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
507
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
508 if (ip_host != NULL) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
509 s1 = "failed to connect to";
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
510 s2 = ip_host;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
511 } else {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
512 s1 = "failed to listen on";
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
513 s2 = ip_port;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
514 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
515
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
516 if (err == EACCES || ip_retry-- == 0)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
517 fmd_hdl_abort(hdl, "%s %s: %s\n", s1, s2, strerror(err));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
518
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
519 fmd_hdl_debug(hdl, "%s %s: %s (will retry)\n", s1, s2, strerror(err));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
520 return (err);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
521 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
522
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
523 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
524 * Timeout handler for the transport module. We use three types of timeouts:
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
525 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
526 * (a) arg is NULL: attempt ip_xprt_setup(), re-install timeout to retry
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
527 * (b) arg is non-NULL, FMD_XPRT_SUSPENDED: call fmd_xprt_resume() on arg
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
528 * (c) arg is non-NULL, !FMD_XPRT_SUSPENDED: call ip_xprt_destroy() on arg
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
529 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
530 * Case (c) is required as we need to cause the module's main thread, which
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
531 * runs this timeout handler, to join with the transport's auxiliary thread.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
532 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
533 static void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
534 ip_timeout(fmd_hdl_t *hdl, id_t id, void *arg)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
535 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
536 ip_xprt_t *ipx = arg;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
537
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
538 if (ipx == NULL) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
539 if (ip_xprt_setup(hdl) != 0)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
540 (void) fmd_timer_install(hdl, NULL, NULL, ip_sleep);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
541 } else if (ipx->ipx_flags & FMD_XPRT_SUSPENDED) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
542 fmd_hdl_debug(hdl, "timer %d waking ipx %p\n", (int)id, arg);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
543 ipx->ipx_flags &= ~FMD_XPRT_SUSPENDED;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
544 fmd_xprt_resume(hdl, ipx->ipx_xprt);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
545 } else {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
546 fmd_hdl_debug(hdl, "timer %d closing ipx %p\n", (int)id, arg);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
547 ip_xprt_destroy(ipx);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
548 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
549 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
550
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
551 static const fmd_prop_t fmd_props[] = {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
552 { "ip_authority", FMD_TYPE_STRING, NULL },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
553 { "ip_bufsize", FMD_TYPE_SIZE, "4k" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
554 { "ip_burp", FMD_TYPE_TIME, "0" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
555 { "ip_enable", FMD_TYPE_BOOL, "false" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
556 { "ip_mtbf", FMD_TYPE_INT32, "0" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
557 { "ip_port", FMD_TYPE_STRING, "664" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
558 { "ip_qlen", FMD_TYPE_INT32, "32" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
559 { "ip_retry", FMD_TYPE_UINT32, "50" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
560 { "ip_server", FMD_TYPE_STRING, NULL },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
561 { "ip_sleep", FMD_TYPE_TIME, "10s" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
562 { "ip_translate", FMD_TYPE_BOOL, "false" },
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
563 { NULL, 0, NULL }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
564 };
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
565
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
566 static const fmd_hdl_ops_t fmd_ops = {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
567 NULL, /* fmdo_recv */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
568 ip_timeout, /* fmdo_timeout */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
569 NULL, /* fmdo_close */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
570 NULL, /* fmdo_stats */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
571 NULL, /* fmdo_gc */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
572 ip_xprt_send, /* fmdo_send */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
573 };
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
574
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
575 static const fmd_hdl_info_t fmd_info = {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
576 "IP Transport Agent", "1.0", &fmd_ops, fmd_props
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
577 };
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
578
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
579 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
580 * Initialize the ip-transport module as either a server or a client. Note
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
581 * that the ip-transport module is not enabled by default under Solaris:
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
582 * at present we require a developer or tool to setprop ip_enable=true.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
583 * If ip-transport is needed in the future out-of-the-box on one or more Sun
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
584 * platforms, the code to check 'ip_enable' should be replaced with:
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
585 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
586 * (a) configuring ip-transport to operate in client mode by default,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
587 * (b) a platform-specific configuration mechanism, or
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
588 * (c) a means to assure security and prevent denial-of-service attacks.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
589 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
590 * Note that (c) is only an issue when the transport module operates
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
591 * in server mode (i.e. with the ip_server property set to NULL) on a
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
592 * generic Solaris system which may be exposed directly to the Internet.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
593 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
594 void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
595 _fmd_init(fmd_hdl_t *hdl)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
596 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
597 struct addrinfo aih;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
598 char *auth, *p, *q, *r, *s;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
599 int err;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
600
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
601 if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
602 return; /* failed to register handle */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
603
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
604 if (fmd_prop_get_int32(hdl, "ip_enable") == FMD_B_FALSE) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
605 fmd_hdl_unregister(hdl);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
606 return;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
607 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
608
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
609 (void) fmd_stat_create(hdl, FMD_STAT_NOALLOC,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
610 sizeof (ip_stat) / sizeof (fmd_stat_t), (fmd_stat_t *)&ip_stat);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
611
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
612 ip_hdl = hdl;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
613 (void) pthread_mutex_init(&ip_lock, NULL);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
614
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
615 ip_burp = fmd_prop_get_int64(hdl, "ip_burp");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
616 ip_mtbf = fmd_prop_get_int32(hdl, "ip_mtbf");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
617 ip_qlen = fmd_prop_get_int32(hdl, "ip_qlen");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
618 ip_retry = fmd_prop_get_int32(hdl, "ip_retry");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
619 ip_sleep = fmd_prop_get_int64(hdl, "ip_sleep");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
620 ip_translate = fmd_prop_get_int32(hdl, "ip_translate");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
621
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
622 ip_size = (size_t)fmd_prop_get_int64(hdl, "ip_bufsize");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
623 ip_size = MAX(ip_size, sizeof (ip_hdr_t));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
624
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
625 ip_host = fmd_prop_get_string(hdl, "ip_server");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
626 ip_port = fmd_prop_get_string(hdl, "ip_port");
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
627
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
628 bzero(&aih, sizeof (aih));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
629 aih.ai_flags = AI_ADDRCONFIG;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
630 aih.ai_family = AF_UNSPEC;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
631 aih.ai_socktype = SOCK_STREAM;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
632
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
633 if (ip_host != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
634 fmd_hdl_debug(hdl, "resolving %s:%s\n", ip_host, ip_port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
635 else
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
636 aih.ai_flags |= AI_PASSIVE;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
637
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
638 err = getaddrinfo(ip_host, ip_port, &aih, &ip_ail);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
639
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
640 if (err != 0) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
641 fmd_prop_free_string(hdl, ip_host);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
642 fmd_prop_free_string(hdl, ip_port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
643
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
644 fmd_hdl_abort(hdl, "failed to resolve host %s port %s: %s\n",
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
645 ip_host ? ip_host : "<none>", ip_port, gai_strerror(err));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
646 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
647
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
648 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
649 * If ip_authority is set, tokenize this string and turn it into an
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
650 * FMA authority represented as a name-value pair list. We will use
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
651 * this authority for all transports created by this module. If
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
652 * ip_authority isn't set, we'll compute authorities on the fly.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
653 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
654 if ((auth = fmd_prop_get_string(hdl, "ip_authority")) != NULL) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
655 (void) nvlist_alloc(&ip_auth, 0, 0);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
656 (void) nvlist_add_uint8(ip_auth,
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
657 FM_VERSION, FM_FMRI_AUTH_VERSION);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
658
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
659 s = alloca(strlen(auth) + 1);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
660 (void) strcpy(s, auth);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
661 fmd_prop_free_string(hdl, auth);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
662
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
663 for (p = strtok_r(s, ",", &q); p != NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
664 p = strtok_r(NULL, ",", &q)) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
665
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
666 if ((r = strchr(p, '=')) == NULL) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
667 fmd_prop_free_string(hdl, ip_host);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
668 fmd_prop_free_string(hdl, ip_port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
669 freeaddrinfo(ip_ail);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
670
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
671 fmd_hdl_abort(hdl, "ip_authority element <%s> "
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
672 "must be in <name>=<value> form\n", p);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
673 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
674
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
675 *r = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
676 (void) nvlist_add_string(ip_auth, p, r + 1);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
677 *r = '=';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
678 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
679 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
680
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
681 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
682 * Call ip_xprt_setup() to connect or bind. If it fails and ip_retry
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
683 * is non-zero, install a timer to try again after 'ip_sleep' nsecs.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
684 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
685 if (ip_xprt_setup(hdl) != 0)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
686 (void) fmd_timer_install(hdl, NULL, NULL, ip_sleep);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
687 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
688
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
689 void
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
690 _fmd_fini(fmd_hdl_t *hdl)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
691 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
692 ip_quit++; /* set quit flag before signalling auxiliary threads */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
693
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
694 while (ip_xps != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
695 ip_xprt_destroy(ip_xps);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
696
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
697 if (ip_auth != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
698 nvlist_free(ip_auth);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
699 if (ip_ail != NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
700 freeaddrinfo(ip_ail);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
701
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
702 fmd_prop_free_string(hdl, ip_host);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
703 fmd_prop_free_string(hdl, ip_port);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
704
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
705 fmd_hdl_unregister(hdl);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
706 }