145039663SJohn Forte /*
245039663SJohn Forte  * CDDL HEADER START
345039663SJohn Forte  *
445039663SJohn Forte  * The contents of this file are subject to the terms of the
545039663SJohn Forte  * Common Development and Distribution License (the "License").
645039663SJohn Forte  * You may not use this file except in compliance with the License.
745039663SJohn Forte  *
845039663SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
945039663SJohn Forte  * or http://www.opensolaris.org/os/licensing.
1045039663SJohn Forte  * See the License for the specific language governing permissions
1145039663SJohn Forte  * and limitations under the License.
1245039663SJohn Forte  *
1345039663SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
1445039663SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1545039663SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
1645039663SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
1745039663SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
1845039663SJohn Forte  *
1945039663SJohn Forte  * CDDL HEADER END
2045039663SJohn Forte  */
2145039663SJohn Forte /*
2245039663SJohn Forte  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2345039663SJohn Forte  * Use is subject to license terms.
2445039663SJohn Forte  */
2545039663SJohn Forte 
26*feb176edSJohn Levon /*
27*feb176edSJohn Levon  * Copyright (c) 2018, Joyent, Inc.
28*feb176edSJohn Levon  */
29*feb176edSJohn Levon 
3045039663SJohn Forte #include <stdio.h>
3145039663SJohn Forte #include <stdlib.h>
3245039663SJohn Forte #include <string.h>
3345039663SJohn Forte #include <strings.h>
3445039663SJohn Forte #include <sys/types.h>
3545039663SJohn Forte #include <errno.h>
3645039663SJohn Forte #include <syslog.h>
3745039663SJohn Forte #include <unistd.h>
3845039663SJohn Forte #include <sys/types.h>
3945039663SJohn Forte #include <sys/socket.h>
4045039663SJohn Forte #include <sys/time.h>
4145039663SJohn Forte #include <netinet/in.h>
4245039663SJohn Forte #include <arpa/inet.h>
4345039663SJohn Forte #include <netdb.h>
4445039663SJohn Forte #include <sys/stat.h>
4545039663SJohn Forte #include <sys/sdt.h>
4645039663SJohn Forte #include <signal.h>
4745039663SJohn Forte #include <fcntl.h>
4845039663SJohn Forte #include <libstmfproxy.h>
4945039663SJohn Forte 
5045039663SJohn Forte /*
5145039663SJohn Forte  * NOTE:
5245039663SJohn Forte  * This is demo code to be used with the existing demo proxy daemon
5345039663SJohn Forte  * svc-stmfproxy in /usr/demo/comstar.
5445039663SJohn Forte  */
5545039663SJohn Forte 
5645039663SJohn Forte struct _s_handle {
5745039663SJohn Forte 	int	sockfd;
5845039663SJohn Forte };
5945039663SJohn Forte 
6045039663SJohn Forte typedef struct _s_handle s_handle_t;
6145039663SJohn Forte 
6245039663SJohn Forte static ssize_t
pt_socket_recv(void * handle,void * buf,size_t len)6345039663SJohn Forte pt_socket_recv(void *handle, void *buf, size_t len)
6445039663SJohn Forte {
6545039663SJohn Forte 	s_handle_t *sh = handle;
6645039663SJohn Forte 
6745039663SJohn Forte 	return (recv(sh->sockfd, buf, len, MSG_WAITALL));
6845039663SJohn Forte }
6945039663SJohn Forte 
7045039663SJohn Forte static ssize_t
pt_socket_send(void * handle,void * buf,size_t len)7145039663SJohn Forte pt_socket_send(void *handle, void *buf, size_t len)
7245039663SJohn Forte {
7345039663SJohn Forte 	s_handle_t *sh = handle;
7445039663SJohn Forte 
7545039663SJohn Forte 	return (send(sh->sockfd, buf, len, 0));
7645039663SJohn Forte }
7745039663SJohn Forte 
7845039663SJohn Forte static void *
pt_socket_connect(int server_node,char * server)7945039663SJohn Forte pt_socket_connect(int server_node, char *server)
8045039663SJohn Forte {
8145039663SJohn Forte 	int sfd, new_sfd;
8245039663SJohn Forte 	s_handle_t *sh = NULL;
8345039663SJohn Forte 	int on = 1;
8445039663SJohn Forte 	struct sockaddr_in cli_addr, serv_addr;
8545039663SJohn Forte 	struct	sockaddr_in sin;
8645039663SJohn Forte 	int cliLen = sizeof (cli_addr);
8745039663SJohn Forte 
8845039663SJohn Forte 	if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
8945039663SJohn Forte 		syslog(LOG_DAEMON|LOG_WARNING,
9045039663SJohn Forte 		    "socket() call failed: %d", errno);
9145039663SJohn Forte 		return (NULL);
9245039663SJohn Forte 	}
9345039663SJohn Forte 
9445039663SJohn Forte 	if (server_node) {
9545039663SJohn Forte 
9645039663SJohn Forte 		if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on,
9745039663SJohn Forte 		    sizeof (on)) < 0) {
9845039663SJohn Forte 			syslog(LOG_DAEMON|LOG_WARNING,
9945039663SJohn Forte 			    "setsockopt() failed: %d", errno);
10045039663SJohn Forte 			goto serv_out;
10145039663SJohn Forte 		}
10245039663SJohn Forte 
10345039663SJohn Forte 		bzero(&serv_addr, sizeof (serv_addr));
10445039663SJohn Forte 		serv_addr.sin_family = AF_INET;
10545039663SJohn Forte 		serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
10645039663SJohn Forte 		/* XXX get from smf? */
10745039663SJohn Forte 		serv_addr.sin_port = htons(6543);
10845039663SJohn Forte 
10945039663SJohn Forte 		if (bind(sfd, (struct sockaddr *)&serv_addr,
11045039663SJohn Forte 		    sizeof (serv_addr)) < 0) {
11145039663SJohn Forte 			syslog(LOG_DAEMON|LOG_WARNING, "bind() call failed: %d",
11245039663SJohn Forte 			    errno);
11345039663SJohn Forte 			goto serv_out;
11445039663SJohn Forte 		}
11545039663SJohn Forte 
11645039663SJohn Forte 		(void) listen(sfd, 5);
11745039663SJohn Forte 
11845039663SJohn Forte 		new_sfd = accept(sfd, (struct sockaddr *)&cli_addr, &cliLen);
11945039663SJohn Forte 
12045039663SJohn Forte 		if (new_sfd < 0) {
12145039663SJohn Forte 			syslog(LOG_DAEMON|LOG_WARNING, "accept failed: %d",
12245039663SJohn Forte 			    errno);
12345039663SJohn Forte 			goto serv_out;
12445039663SJohn Forte 		}
12545039663SJohn Forte 		sh = malloc(sizeof (*sh));
12645039663SJohn Forte 		sh->sockfd = new_sfd;
12745039663SJohn Forte serv_out:
128*feb176edSJohn Levon 		(void) close(sfd);
12945039663SJohn Forte 	} else {
13045039663SJohn Forte 		struct	hostent *hp;
13145039663SJohn Forte 
13245039663SJohn Forte 		/*
13345039663SJohn Forte 		 * Assume IP dot notation or if that fails, gethostbyname()
13445039663SJohn Forte 		 * If that fails, return
13545039663SJohn Forte 		 */
13645039663SJohn Forte 		if ((inet_aton(server, &sin.sin_addr)) == 0) {
13745039663SJohn Forte 			if ((hp = gethostbyname(server)) != NULL) {
13845039663SJohn Forte 				memcpy(&sin.sin_addr.s_addr, hp->h_addr,
13945039663SJohn Forte 				    hp->h_length);
14045039663SJohn Forte 			} else {
14145039663SJohn Forte 				syslog(LOG_DAEMON|LOG_CRIT,
14245039663SJohn Forte 				    "Cannot get IP address for %s", server);
14345039663SJohn Forte 				(void) close(sfd);
14445039663SJohn Forte 				return (NULL);
14545039663SJohn Forte 			}
14645039663SJohn Forte 		} else {
14745039663SJohn Forte 			fprintf(stderr,
14845039663SJohn Forte 			    "Sorry, cannot use ip address format\n");
14945039663SJohn Forte 			(void) close(sfd);
15045039663SJohn Forte 			return (NULL);
15145039663SJohn Forte 		}
15245039663SJohn Forte 		sin.sin_family = AF_INET;
15345039663SJohn Forte 		/* XXX pass in from smf */
15445039663SJohn Forte 		sin.sin_port = htons(6543);
15545039663SJohn Forte 
15645039663SJohn Forte 		while (connect(sfd, (struct sockaddr *)&sin,
15745039663SJohn Forte 		    sizeof (sin)) < 0) {
158*feb176edSJohn Levon 			(void) close(sfd);
15945039663SJohn Forte 			if (errno == ECONNREFUSED) {
16045039663SJohn Forte 				/* get a fresh socket and retry */
16145039663SJohn Forte 				sfd = socket(AF_INET, SOCK_STREAM, 0);
16245039663SJohn Forte 				if (sfd < 0) {
16345039663SJohn Forte 					syslog(LOG_DAEMON|LOG_WARNING,
16445039663SJohn Forte 					    "socket() call failed: %d", errno);
16545039663SJohn Forte 					return (NULL);
16645039663SJohn Forte 				}
167*feb176edSJohn Levon 				(void) sleep(2);
16845039663SJohn Forte 			} else {
16945039663SJohn Forte 				syslog(LOG_DAEMON|LOG_CRIT,
17045039663SJohn Forte 				    "Cannot connect %s - %d", server, errno);
17145039663SJohn Forte 				return (NULL);
17245039663SJohn Forte 			}
17345039663SJohn Forte 		}
17445039663SJohn Forte 		sh = malloc(sizeof (*sh));
17545039663SJohn Forte 		sh->sockfd = sfd;
17645039663SJohn Forte 	}
17745039663SJohn Forte 	return (sh);
17845039663SJohn Forte }
17945039663SJohn Forte 
18045039663SJohn Forte pt_ops_t pt_socket_ops = {
18145039663SJohn Forte 	pt_socket_connect,
18245039663SJohn Forte 	pt_socket_send,
18345039663SJohn Forte 	pt_socket_recv
18445039663SJohn Forte };
18545039663SJohn Forte 
18645039663SJohn Forte int
stmf_proxy_transport_init(char * transport,pt_ops_t ** pt_ops)18745039663SJohn Forte stmf_proxy_transport_init(char *transport, pt_ops_t **pt_ops)
18845039663SJohn Forte {
18945039663SJohn Forte 	if (strcmp(transport, "sockets") == 0) {
19045039663SJohn Forte 		*pt_ops = &pt_socket_ops;
19145039663SJohn Forte 		return (0);
19245039663SJohn Forte 	} else {
19345039663SJohn Forte 		return (-1);
19445039663SJohn Forte 	}
19545039663SJohn Forte }
196