added connection name to IKE_SA title
[strongswan.git] / src / manager / gateway.c
1 /**
2 * @file gateway.c
3 *
4 * @brief Implementation of gateway_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "gateway.h"
24
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <unistd.h>
28 #include <string.h>
29
30 typedef struct private_gateway_t private_gateway_t;
31
32 /**
33 * private data of gateway
34 */
35 struct private_gateway_t {
36
37 /**
38 * public functions
39 */
40 gateway_t public;
41
42 /**
43 * name of the gateway
44 */
45 char *name;
46
47 /**
48 * connection information
49 */
50 host_t *host;
51
52 /**
53 * socket file descriptor, > 0 if connected
54 */
55 int fd;
56 };
57
58 /**
59 * establish connection to gateway
60 */
61 static bool connect_(private_gateway_t *this)
62 {
63 if (this->fd >= 0)
64 {
65 close(this->fd);
66 }
67 this->fd = socket(AF_INET, SOCK_STREAM, 0);
68 if (this->fd < 0)
69 {
70 return FALSE;
71 }
72 if (connect(this->fd, this->host->get_sockaddr(this->host),
73 *this->host->get_sockaddr_len(this->host)) != 0)
74 {
75 close(this->fd);
76 this->fd = -1;
77 return FALSE;
78 }
79 return TRUE;
80 }
81
82
83 /**
84 * Implementation of gateway_t.request.
85 */
86 static char* request(private_gateway_t *this, char *xml)
87 {
88 if (this->fd < 0)
89 {
90 if (!connect_(this))
91 {
92 return NULL;
93 }
94 }
95 while (TRUE)
96 {
97 char buf[8096];
98 ssize_t len;
99
100 len = strlen(xml);
101 if (send(this->fd, xml, len, 0) != len)
102 {
103 return NULL;
104 }
105 len = recv(this->fd, buf, sizeof(buf) - 1, 0);
106 if (len < 0)
107 {
108 return NULL;
109 }
110 if (len == 0)
111 {
112 if (!connect_(this))
113 {
114 return NULL;
115 }
116 continue;
117 }
118 buf[len] = 0;
119 return strdup(buf);
120 }
121 }
122
123 /**
124 * Implementation of gateway_t.destroy
125 */
126 static void destroy(private_gateway_t *this)
127 {
128 if (this->fd >= 0)
129 {
130 close(this->fd);
131 }
132 this->host->destroy(this->host);
133 free(this->name);
134 free(this);
135 }
136
137 /*
138 * see header file
139 */
140 gateway_t *gateway_create(char *name, host_t *host)
141 {
142 private_gateway_t *this = malloc_thing(private_gateway_t);
143
144 this->public.request = (char*(*)(gateway_t*, char *xml))request;
145 this->public.destroy = (void(*)(gateway_t*))destroy;
146
147 this->name = strdup(name);
148 this->host = host;
149 this->fd = -1;
150
151 return &this->public;
152 }
153