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