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