2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include <netinet/in.h>
19 #include <sys/socket.h>
23 #include "input_conn.h"
26 #include "cmd_parser.h"
28 static struct input tcp_server;
29 int tcp_server_started;
30 static struct input uds_server;
31 int uds_server_started;
41 struct client_conn clients[32];
43 static int start_listen_tcp(void)
45 struct sockaddr_in server;
49 memset(&server, 0, sizeof(server));
50 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
55 server.sin_family = AF_INET;
56 server.sin_port = ntohs(8474);
57 server.sin_addr.s_addr = ntohl(INADDR_ANY);
59 ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int));
64 if (bind(sock, (struct sockaddr *) &server, sizeof(server)) == -1)
67 if (listen(sock, 1) == -1)
73 static int start_listen_uds(void)
76 struct sockaddr_un server = {
77 .sun_path = "/tmp/prox.sock",
81 sock = socket(AF_UNIX, SOCK_STREAM, 0);
85 /* Unlink can fail, i.e. when /tmp/prox.sock does not
86 exists. This is not fatal. */
87 unlink(server.sun_path);
89 if (bind(sock, (struct sockaddr *) &server, sizeof(server)) == -1)
92 if (listen(sock, 1) == -1)
98 static void write_client(struct input *input, const char *buf, size_t len)
102 while ((ret = write(input->fd, buf, len)) != (int)len) {
108 static void handle_client(struct input* client_input)
113 struct client_conn *c = NULL;
115 /* Get the client structure that uses this input */
116 for (i = 0; i < sizeof(clients)/sizeof(clients[0]); ++i) {
117 if (&clients[i].input == client_input) {
123 /* handle_client function called non-tcp client */
127 ret = read(c->input.fd, cur, sizeof(cur));
131 unreg_input(&c->input);
135 /* Scan in data until \n (\r skipped if followed by \n) */
136 for (int i = 0; i < ret; ++i) {
137 if (cur[i] == '\r' && i + 1 < ret && cur[i + 1] == '\n')
140 if (cur[i] == '\n') {
141 c->buf[c->n_buf] = 0;
143 cmd_parser_parse(c->buf, client_input);
146 else if (c->n_buf + 1 < (int)sizeof(c->buf))
147 c->buf[c->n_buf++] = cur[i];
153 static void handle_new_client(struct input* server)
157 int new_client = accept(server->fd, NULL, NULL);
159 for (i = 0; i < sizeof(clients)/sizeof(clients[0]); ++i) {
160 if (clients[i].enabled == 0) {
165 if (i == sizeof(clients)/sizeof(clients[0])) {
170 clients[i].enabled = 1;
171 clients[i].n_buf = 0;
172 clients[i].input.fd = new_client;
173 clients[i].input.reply = server->reply;
174 clients[i].input.proc_input = handle_client;
176 reg_input(&clients[i].input);
179 int reg_input_tcp(void)
183 if (tcp_server_started)
185 if ((fd = start_listen_tcp()) < 0)
189 tcp_server.proc_input = handle_new_client;
190 tcp_server.reply = write_client;
191 if (reg_input(&tcp_server) != 0) {
195 tcp_server_started = 1;
199 int reg_input_uds(void)
203 if (uds_server_started)
206 if ((fd = start_listen_uds()) < 0)
210 uds_server.proc_input = handle_new_client;
211 uds_server.reply = write_client;
212 if (reg_input(&uds_server) != 0) {
216 uds_server_started = 1;
220 void unreg_input_tcp(void)
222 if (!tcp_server_started)
224 tcp_server_started = 0;
225 close(tcp_server.fd);
226 unreg_input(&tcp_server);
229 void unreg_input_uds(void)
231 if (!uds_server_started)
233 uds_server_started = 0;
234 close(tcp_server.fd);
235 unreg_input(&tcp_server);