xref: /titanic_44/usr/src/lib/libstmfproxy/common/stmftransport.c (revision 450396635f70344c58b6b1e4db38cf17ff34445c)
1*45039663SJohn Forte /*
2*45039663SJohn Forte  * CDDL HEADER START
3*45039663SJohn Forte  *
4*45039663SJohn Forte  * The contents of this file are subject to the terms of the
5*45039663SJohn Forte  * Common Development and Distribution License (the "License").
6*45039663SJohn Forte  * You may not use this file except in compliance with the License.
7*45039663SJohn Forte  *
8*45039663SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*45039663SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*45039663SJohn Forte  * See the License for the specific language governing permissions
11*45039663SJohn Forte  * and limitations under the License.
12*45039663SJohn Forte  *
13*45039663SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*45039663SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*45039663SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*45039663SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*45039663SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*45039663SJohn Forte  *
19*45039663SJohn Forte  * CDDL HEADER END
20*45039663SJohn Forte  */
21*45039663SJohn Forte /*
22*45039663SJohn Forte  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*45039663SJohn Forte  * Use is subject to license terms.
24*45039663SJohn Forte  */
25*45039663SJohn Forte 
26*45039663SJohn Forte #include <stdio.h>
27*45039663SJohn Forte #include <stdlib.h>
28*45039663SJohn Forte #include <string.h>
29*45039663SJohn Forte #include <strings.h>
30*45039663SJohn Forte #include <sys/types.h>
31*45039663SJohn Forte #include <errno.h>
32*45039663SJohn Forte #include <syslog.h>
33*45039663SJohn Forte #include <unistd.h>
34*45039663SJohn Forte #include <sys/types.h>
35*45039663SJohn Forte #include <sys/socket.h>
36*45039663SJohn Forte #include <sys/time.h>
37*45039663SJohn Forte #include <netinet/in.h>
38*45039663SJohn Forte #include <arpa/inet.h>
39*45039663SJohn Forte #include <netdb.h>
40*45039663SJohn Forte #include <sys/stat.h>
41*45039663SJohn Forte #include <sys/sdt.h>
42*45039663SJohn Forte #include <signal.h>
43*45039663SJohn Forte #include <fcntl.h>
44*45039663SJohn Forte #include <libstmfproxy.h>
45*45039663SJohn Forte 
46*45039663SJohn Forte /*
47*45039663SJohn Forte  * NOTE:
48*45039663SJohn Forte  * This is demo code to be used with the existing demo proxy daemon
49*45039663SJohn Forte  * svc-stmfproxy in /usr/demo/comstar.
50*45039663SJohn Forte  */
51*45039663SJohn Forte 
52*45039663SJohn Forte struct _s_handle {
53*45039663SJohn Forte 	int	sockfd;
54*45039663SJohn Forte };
55*45039663SJohn Forte 
56*45039663SJohn Forte typedef struct _s_handle s_handle_t;
57*45039663SJohn Forte 
58*45039663SJohn Forte static ssize_t
pt_socket_recv(void * handle,void * buf,size_t len)59*45039663SJohn Forte pt_socket_recv(void *handle, void *buf, size_t len)
60*45039663SJohn Forte {
61*45039663SJohn Forte 	s_handle_t *sh = handle;
62*45039663SJohn Forte 
63*45039663SJohn Forte 	return (recv(sh->sockfd, buf, len, MSG_WAITALL));
64*45039663SJohn Forte }
65*45039663SJohn Forte 
66*45039663SJohn Forte static ssize_t
pt_socket_send(void * handle,void * buf,size_t len)67*45039663SJohn Forte pt_socket_send(void *handle, void *buf, size_t len)
68*45039663SJohn Forte {
69*45039663SJohn Forte 	s_handle_t *sh = handle;
70*45039663SJohn Forte 
71*45039663SJohn Forte 	return (send(sh->sockfd, buf, len, 0));
72*45039663SJohn Forte }
73*45039663SJohn Forte 
74*45039663SJohn Forte static void *
pt_socket_connect(int server_node,char * server)75*45039663SJohn Forte pt_socket_connect(int server_node, char *server)
76*45039663SJohn Forte {
77*45039663SJohn Forte 	int sfd, new_sfd;
78*45039663SJohn Forte 	s_handle_t *sh = NULL;
79*45039663SJohn Forte 	int on = 1;
80*45039663SJohn Forte 	struct sockaddr_in cli_addr, serv_addr;
81*45039663SJohn Forte 	struct	sockaddr_in sin;
82*45039663SJohn Forte 	int cliLen = sizeof (cli_addr);
83*45039663SJohn Forte 
84*45039663SJohn Forte 	if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
85*45039663SJohn Forte 		syslog(LOG_DAEMON|LOG_WARNING,
86*45039663SJohn Forte 		    "socket() call failed: %d", errno);
87*45039663SJohn Forte 		return (NULL);
88*45039663SJohn Forte 	}
89*45039663SJohn Forte 
90*45039663SJohn Forte 	if (server_node) {
91*45039663SJohn Forte 
92*45039663SJohn Forte 		if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on,
93*45039663SJohn Forte 		    sizeof (on)) < 0) {
94*45039663SJohn Forte 			syslog(LOG_DAEMON|LOG_WARNING,
95*45039663SJohn Forte 			    "setsockopt() failed: %d", errno);
96*45039663SJohn Forte 			goto serv_out;
97*45039663SJohn Forte 		}
98*45039663SJohn Forte 
99*45039663SJohn Forte 		bzero(&serv_addr, sizeof (serv_addr));
100*45039663SJohn Forte 		serv_addr.sin_family = AF_INET;
101*45039663SJohn Forte 		serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
102*45039663SJohn Forte 		/* XXX get from smf? */
103*45039663SJohn Forte 		serv_addr.sin_port = htons(6543);
104*45039663SJohn Forte 
105*45039663SJohn Forte 		if (bind(sfd, (struct sockaddr *)&serv_addr,
106*45039663SJohn Forte 		    sizeof (serv_addr)) < 0) {
107*45039663SJohn Forte 			syslog(LOG_DAEMON|LOG_WARNING, "bind() call failed: %d",
108*45039663SJohn Forte 			    errno);
109*45039663SJohn Forte 			goto serv_out;
110*45039663SJohn Forte 		}
111*45039663SJohn Forte 
112*45039663SJohn Forte 		(void) listen(sfd, 5);
113*45039663SJohn Forte 
114*45039663SJohn Forte 		new_sfd = accept(sfd, (struct sockaddr *)&cli_addr, &cliLen);
115*45039663SJohn Forte 
116*45039663SJohn Forte 		if (new_sfd < 0) {
117*45039663SJohn Forte 			syslog(LOG_DAEMON|LOG_WARNING, "accept failed: %d",
118*45039663SJohn Forte 			    errno);
119*45039663SJohn Forte 			goto serv_out;
120*45039663SJohn Forte 		}
121*45039663SJohn Forte 		sh = malloc(sizeof (*sh));
122*45039663SJohn Forte 		sh->sockfd = new_sfd;
123*45039663SJohn Forte serv_out:
124*45039663SJohn Forte 		close(sfd);
125*45039663SJohn Forte 	} else {
126*45039663SJohn Forte 		struct	hostent *hp;
127*45039663SJohn Forte 
128*45039663SJohn Forte 		/*
129*45039663SJohn Forte 		 * Assume IP dot notation or if that fails, gethostbyname()
130*45039663SJohn Forte 		 * If that fails, return
131*45039663SJohn Forte 		 */
132*45039663SJohn Forte 		if ((inet_aton(server, &sin.sin_addr)) == 0) {
133*45039663SJohn Forte 			if ((hp = gethostbyname(server)) != NULL) {
134*45039663SJohn Forte 				memcpy(&sin.sin_addr.s_addr, hp->h_addr,
135*45039663SJohn Forte 				    hp->h_length);
136*45039663SJohn Forte 			} else {
137*45039663SJohn Forte 				syslog(LOG_DAEMON|LOG_CRIT,
138*45039663SJohn Forte 				    "Cannot get IP address for %s", server);
139*45039663SJohn Forte 				(void) close(sfd);
140*45039663SJohn Forte 				return (NULL);
141*45039663SJohn Forte 			}
142*45039663SJohn Forte 		} else {
143*45039663SJohn Forte 			fprintf(stderr,
144*45039663SJohn Forte 			    "Sorry, cannot use ip address format\n");
145*45039663SJohn Forte 			(void) close(sfd);
146*45039663SJohn Forte 			return (NULL);
147*45039663SJohn Forte 		}
148*45039663SJohn Forte 		sin.sin_family = AF_INET;
149*45039663SJohn Forte 		/* XXX pass in from smf */
150*45039663SJohn Forte 		sin.sin_port = htons(6543);
151*45039663SJohn Forte 
152*45039663SJohn Forte 		while (connect(sfd, (struct sockaddr *)&sin,
153*45039663SJohn Forte 		    sizeof (sin)) < 0) {
154*45039663SJohn Forte 			close(sfd);
155*45039663SJohn Forte 			if (errno == ECONNREFUSED) {
156*45039663SJohn Forte 				/* get a fresh socket and retry */
157*45039663SJohn Forte 				sfd = socket(AF_INET, SOCK_STREAM, 0);
158*45039663SJohn Forte 				if (sfd < 0) {
159*45039663SJohn Forte 					syslog(LOG_DAEMON|LOG_WARNING,
160*45039663SJohn Forte 					    "socket() call failed: %d", errno);
161*45039663SJohn Forte 					return (NULL);
162*45039663SJohn Forte 				}
163*45039663SJohn Forte 				sleep(2);
164*45039663SJohn Forte 			} else {
165*45039663SJohn Forte 				syslog(LOG_DAEMON|LOG_CRIT,
166*45039663SJohn Forte 				    "Cannot connect %s - %d", server, errno);
167*45039663SJohn Forte 				return (NULL);
168*45039663SJohn Forte 			}
169*45039663SJohn Forte 		}
170*45039663SJohn Forte 		sh = malloc(sizeof (*sh));
171*45039663SJohn Forte 		sh->sockfd = sfd;
172*45039663SJohn Forte 	}
173*45039663SJohn Forte 	return (sh);
174*45039663SJohn Forte }
175*45039663SJohn Forte 
176*45039663SJohn Forte pt_ops_t pt_socket_ops = {
177*45039663SJohn Forte 	pt_socket_connect,
178*45039663SJohn Forte 	pt_socket_send,
179*45039663SJohn Forte 	pt_socket_recv
180*45039663SJohn Forte };
181*45039663SJohn Forte 
182*45039663SJohn Forte int
stmf_proxy_transport_init(char * transport,pt_ops_t ** pt_ops)183*45039663SJohn Forte stmf_proxy_transport_init(char *transport, pt_ops_t **pt_ops)
184*45039663SJohn Forte {
185*45039663SJohn Forte 	if (strcmp(transport, "sockets") == 0) {
186*45039663SJohn Forte 		*pt_ops = &pt_socket_ops;
187*45039663SJohn Forte 		return (0);
188*45039663SJohn Forte 	} else {
189*45039663SJohn Forte 		return (-1);
190*45039663SJohn Forte 	}
191*45039663SJohn Forte }
192