blob: 8d662f6859d12d7141b8947d55a711f35888e04a [file] [log] [blame]
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +02001/*
2 * osmo-pcap-server code
3 *
Holger Hans Peter Freyther6413e762016-08-26 15:24:40 +02004 * (C) 2011-2016 by Holger Hans Peter Freyther <holger@moiji-mobile.com>
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +02005 * (C) 2011 by On-Waves
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include <osmo-pcap/osmo_pcap_server.h>
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +020024#include <osmo-pcap/common.h>
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +020025#include <osmo-pcap/wireformat.h>
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +020026
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +020027#include <osmocom/core/socket.h>
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +020028#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +020029#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +020030
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +020031#include <arpa/inet.h>
32#include <sys/socket.h>
33#include <sys/types.h>
34
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +020035#include <zmq.h>
36
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +020037#include <fcntl.h>
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +020038#include <errno.h>
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +020039#include <string.h>
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +020040#include <unistd.h>
41
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +020042static void pcap_zmq_send(void *publ, const void *data, size_t len, int flags)
43{
44 int rc;
45 zmq_msg_t msg;
46
47 rc = zmq_msg_init_size(&msg, len);
48 if (rc != 0) {
49 /* sigh.. we said SNDMORE but can't... */
50 LOGP(DSERVER, LOGL_ERROR, "Failed to init rc=%d errno=%d/%s\n",
51 rc, errno, strerror(errno));
52 return;
53 }
54 memcpy(zmq_msg_data(&msg), data, len);
55 rc = zmq_msg_send(&msg, publ, flags);
56 if (rc == -1) {
57 /* is the zmq_msg now owned? leak??? */
58 LOGP(DSERVER, LOGL_ERROR, "Failed to send data rc=%d errno=%d/%s\n",
59 rc, errno, strerror(errno));
60 return;
61 }
62}
63
64static void client_event(struct osmo_pcap_conn *conn,
65 const char *event, const char *data)
66{
67 char *event_name;
68
69 if (!conn->server->zmq_publ)
70 return;
71
72 /*
73 * This multi-part support is insane... so if we lose the first
74 * or the last part of the multipart message stuff is going out
75 * of sync. *great* As we can't do anything about it right now
76 * just close the eyese and send it.
77 */
78 event_name = talloc_asprintf(conn, "event.v1.%s.%s",
79 event, conn->name);
80 pcap_zmq_send(conn->server->zmq_publ,
81 event_name, strlen(event_name),
82 data ? ZMQ_SNDMORE : 0);
83 talloc_free(event_name);
84 if (data)
85 pcap_zmq_send(conn->server->zmq_publ, data, strlen(data), 0);
86}
87
88static void client_data(struct osmo_pcap_conn *conn,
89 struct osmo_pcap_data *data)
90{
91 char *event_name;
92
93 if (!conn->server->zmq_publ)
94 return;
95
96 /*
97 * This multi-part support is insane... so if we lose the first
98 * or the last part of the multipart message stuff is going out
99 * of sync. *great* As we can't do anything about it right now
100 * just close the eyese and send it.
101 */
102 event_name = talloc_asprintf(conn, "data.v1.%s", conn->name);
103 pcap_zmq_send(conn->server->zmq_publ, event_name, strlen(event_name), ZMQ_SNDMORE);
104 talloc_free(event_name);
105
106 pcap_zmq_send(conn->server->zmq_publ,
107 &conn->file_hdr, sizeof(conn->file_hdr),
108 ZMQ_SNDMORE);
109 pcap_zmq_send(conn->server->zmq_publ,
110 &data->data[0], data->len,
111 0);
112}
113
114void osmo_pcap_server_close_trace(struct osmo_pcap_conn *conn)
115{
116 if (conn->local_fd >= 0) {
117 close(conn->local_fd);
118 conn->local_fd = -1;
119 }
120
121 if (conn->curr_filename) {
122 client_event(conn, "closingtracefile", conn->curr_filename);
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200123 rate_ctr_inc(&conn->ctrg->ctr[PEER_CTR_PROTATE]);
124 rate_ctr_inc(&conn->server->ctrg->ctr[SERVER_CTR_PROTATE]);
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200125 talloc_free(conn->curr_filename);
126 conn->curr_filename = NULL;
127 }
128}
129
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200130static void close_connection(struct osmo_pcap_conn *conn)
131{
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200132 if (conn->rem_wq.bfd.fd >= 0) {
133 close(conn->rem_wq.bfd.fd);
134 conn->rem_wq.bfd.fd = -1;
135 osmo_fd_unregister(&conn->rem_wq.bfd);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200136 }
137
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200138 osmo_pcap_server_close_trace(conn);
139 client_event(conn, "disconnect", NULL);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200140}
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200141
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200142static void restart_pcap(struct osmo_pcap_conn *conn)
143{
144 time_t now = time(NULL);
145 struct tm *tm = localtime(&now);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200146 int rc;
147
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200148 osmo_pcap_server_close_trace(conn);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200149
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200150 /* omit any storing/creation of the file */
151 if (conn->no_store) {
152 conn->last_write = *tm;
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200153 talloc_free(conn->curr_filename);
154 conn->curr_filename = NULL;
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200155 return;
156 }
157
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200158 conn->curr_filename = talloc_asprintf(conn, "%s/trace-%s-%d%.2d%.2d_%.2d%.2d%.2d.pcap",
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200159 conn->server->base_path, conn->name,
160 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
161 tm->tm_hour, tm->tm_min, tm->tm_sec);
Daniel Willmannde773862011-07-17 17:48:17 +0200162
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200163 if (!conn->curr_filename) {
Daniel Willmannde773862011-07-17 17:48:17 +0200164 LOGP(DSERVER, LOGL_ERROR, "Failed to assemble filename for %s.\n", conn->name);
165 return;
166 }
167
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200168 conn->local_fd = creat(conn->curr_filename, 0440);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200169 if (conn->local_fd < 0) {
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200170 LOGP(DSERVER, LOGL_ERROR, "Failed to file: '%s'\n", conn->curr_filename);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200171 return;
172 }
173
174 rc = write(conn->local_fd, &conn->file_hdr, sizeof(conn->file_hdr));
175 if (rc != sizeof(conn->file_hdr)) {
176 LOGP(DSERVER, LOGL_ERROR, "Failed to write the header: %d\n", errno);
177 close(conn->local_fd);
178 conn->local_fd = -1;
179 return;
180 }
181
182 conn->last_write = *tm;
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200183}
184
185static void link_data(struct osmo_pcap_conn *conn, struct osmo_pcap_data *data)
186{
187 struct pcap_file_header *hdr;
188
189 if (data->len != sizeof(*hdr)) {
190 LOGP(DSERVER, LOGL_ERROR, "The pcap_file_header does not fit.\n");
191 close_connection(conn);
192 return;
193 }
194
195 hdr = (struct pcap_file_header *) &data->data[0];
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200196 if (!conn->no_store && conn->local_fd < 0) {
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200197 conn->file_hdr = *hdr;
198 restart_pcap(conn);
199 } else if (memcmp(&conn->file_hdr, hdr, sizeof(*hdr)) != 0) {
200 conn->file_hdr = *hdr;
201 restart_pcap(conn);
202 }
203}
204
205/*
206 * Check if we are past the limit or on a day change
207 */
208static void write_data(struct osmo_pcap_conn *conn, struct osmo_pcap_data *data)
209{
210 time_t now = time(NULL);
211 struct tm *tm = localtime(&now);
212 int rc;
213
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200214 client_data(conn, data);
215
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200216 if (conn->no_store) {
217 conn->last_write = *tm;
218 return;
219 }
220
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200221 if (conn->local_fd < -1) {
222 LOGP(DSERVER, LOGL_ERROR, "No file is open. close connection.\n");
223 close_connection(conn);
224 return;
225 }
226
227 off_t cur = lseek(conn->local_fd, 0, SEEK_CUR);
228 if (cur > conn->server->max_size) {
229 LOGP(DSERVER, LOGL_NOTICE, "Rolling over file for %s\n", conn->name);
230 restart_pcap(conn);
231 } else if (conn->last_write.tm_mday != tm->tm_mday ||
232 conn->last_write.tm_mon != tm->tm_mon ||
233 conn->last_write.tm_year != tm->tm_year) {
234 LOGP(DSERVER, LOGL_NOTICE, "Rolling over file for %s\n", conn->name);
235 restart_pcap(conn);
236 }
237
238 conn->last_write = *tm;
239 rc = write(conn->local_fd, &data->data[0], data->len);
240 if (rc != data->len) {
241 LOGP(DSERVER, LOGL_ERROR, "Failed to write for %s\n", conn->name);
242 close_connection(conn);
243 }
244}
245
246
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200247void osmo_pcap_server_delete(struct osmo_pcap_conn *conn)
248{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200249 close_connection(conn);
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200250 llist_del(&conn->entry);
251 talloc_free(conn);
252}
253
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200254struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
255 const char *name)
256{
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200257 struct rate_ctr_group_desc *desc;
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200258 struct osmo_pcap_conn *conn;
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200259
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200260 llist_for_each_entry(conn, &server->conn, entry) {
261 if (strcmp(conn->name, name) == 0)
262 return conn;
263 }
264
265 conn = talloc_zero(server, struct osmo_pcap_conn);
266 if (!conn) {
267 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200268 "Failed to allocate the connection peer=%s.\n", name);
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200269 return NULL;
270 }
271
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200272 /* a bit nasty. we do not work with ids but names */
273 desc = talloc_zero(conn, struct rate_ctr_group_desc);
274 if (!desc) {
275 LOGP(DSERVER, LOGL_ERROR,
276 "Failed to allocate rate ctr desc peer=%s\n", name);
277 talloc_free(conn);
278 return NULL;
279 }
280 memcpy(desc, &pcap_peer_group_desc, sizeof(pcap_peer_group_desc));
281 desc->group_name_prefix = talloc_asprintf(desc, "pcap.peer.%s", name);
282 if (!desc->group_name_prefix) {
283 LOGP(DSERVER, LOGL_ERROR,
284 "Failed to allocate group name prefix peer=%s\n", name);
285 talloc_free(conn);
286 return NULL;
287 }
288 desc->group_description = talloc_asprintf(desc, "PCAP peer statistics %s", name);
289 if (!desc->group_description) {
290 LOGP(DSERVER, LOGL_ERROR,
291 "Failed to allocate group description peer=%s\n", name);
292 talloc_free(conn);
293 return NULL;
294 }
295
296 conn->ctrg = rate_ctr_group_alloc(desc, desc, 0);
297 if (!conn->ctrg) {
298 LOGP(DSERVER, LOGL_ERROR,
299 "Failed to allocate rate ctr peer=%s\n", name);
300 talloc_free(conn);
301 return NULL;
302 }
303
304
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200305 conn->name = talloc_strdup(conn, name);
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200306 /* we never write */
307 osmo_wqueue_init(&conn->rem_wq, 0);
308 conn->rem_wq.bfd.fd = -1;
Holger Hans Peter Freytherdc3d1dc2011-06-01 16:32:29 +0200309 conn->local_fd = -1;
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200310 conn->server = server;
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200311 conn->data = (struct osmo_pcap_data *) &conn->buf[0];
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200312 llist_add_tail(&conn->entry, &server->conn);
313 return conn;
314}
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200315
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200316static int read_cb_initial(struct osmo_fd *fd, struct osmo_pcap_conn *conn)
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200317{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200318 int rc;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200319 rc = read(fd->fd, &conn->buf[sizeof(*conn->data) - conn->pend], conn->pend);
320 if (rc <= 0) {
321 LOGP(DSERVER, LOGL_ERROR,
322 "Too short packet. Got %d, wanted %d\n", rc, conn->data->len);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200323 close_connection(conn);
324 return -1;
325 }
326
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200327 conn->pend -= rc;
328 if (conn->pend < 0) {
329 LOGP(DSERVER, LOGL_ERROR,
330 "Someone got the pending read wrong: %d\n", conn->pend);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200331 close_connection(conn);
332 return -1;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200333 } else if (conn->pend == 0) {
334 conn->data->len = ntohs(conn->data->len);
335
Holger Hans Peter Freytherff1a5dc2015-12-03 19:32:04 +0100336 if (conn->data->len > SERVER_MAX_DATA_SIZE) {
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200337 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther26327bd2015-12-03 19:29:38 +0100338 "Implausible data length: %u\n", conn->data->len);
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200339 close_connection(conn);
340 return -1;
341 }
342
343 conn->state = STATE_DATA;
344 conn->pend = conn->data->len;
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200345 }
346
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200347 return 0;
348}
349
350static int read_cb_data(struct osmo_fd *fd, struct osmo_pcap_conn *conn)
351{
352 int rc;
353 rc = read(fd->fd, &conn->data->data[conn->data->len - conn->pend], conn->pend);
354 if (rc <= 0) {
Holger Hans Peter Freyther59bfb582011-06-01 17:00:12 +0200355 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200356 "Too short packet. Got %d, wanted %d\n", rc, conn->data->len);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200357 close_connection(conn);
358 return -1;
359 }
360
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200361 conn->pend -= rc;
362 if (conn->pend < 0) {
363 LOGP(DSERVER, LOGL_ERROR,
364 "Someone got the pending read wrong: %d\n", conn->pend);
365 close_connection(conn);
366 return -1;
367 } else if (conn->pend == 0) {
368 conn->state = STATE_INITIAL;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200369 conn->pend = sizeof(*conn->data);
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200370
371 /* count the full packet we got */
372 rate_ctr_inc(&conn->ctrg->ctr[PEER_CTR_PKTS]);
373 rate_ctr_inc(&conn->server->ctrg->ctr[SERVER_CTR_PKTS]);
374
375 /* count the bytes of it */
376 rate_ctr_add(&conn->ctrg->ctr[PEER_CTR_BYTES], conn->data->len);
377 rate_ctr_add(&conn->server->ctrg->ctr[SERVER_CTR_BYTES], conn->data->len);
378
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200379 switch (conn->data->type) {
380 case PKT_LINK_HDR:
381 link_data(conn, conn->data);
382 break;
383 case PKT_LINK_DATA:
384 write_data(conn, conn->data);
385 break;
386 }
387 }
388
389 return 0;
390}
391
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200392static int read_cb(struct osmo_fd *fd)
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200393{
394 struct osmo_pcap_conn *conn;
395
396 conn = fd->data;
397
398 if (conn->state == STATE_INITIAL) {
Daniel Willmannc7401c62011-07-17 17:48:18 +0200399 if (conn->reopen) {
400 LOGP(DSERVER, LOGL_INFO, "Reopening log for %s now.\n", conn->name);
401 restart_pcap(conn);
402 conn->reopen = 0;
403 }
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200404 return read_cb_initial(fd, conn);
405 } else if (conn->state == STATE_DATA) {
406 return read_cb_data(fd, conn);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200407 }
408
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200409 return 0;
410}
411
412static void new_connection(struct osmo_pcap_server *server,
413 struct osmo_pcap_conn *client, int new_fd)
414{
415 close_connection(client);
416
417 memset(&client->file_hdr, 0, sizeof(client->file_hdr));
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200418 client->rem_wq.bfd.fd = new_fd;
419 if (osmo_fd_register(&client->rem_wq.bfd) != 0) {
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200420 LOGP(DSERVER, LOGL_ERROR, "Failed to register fd.\n");
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200421 client->rem_wq.bfd.fd = -1;
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200422 close(new_fd);
423 return;
424 }
425
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200426 rate_ctr_inc(&client->ctrg->ctr[PEER_CTR_CONNECT]);
427
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200428 client->rem_wq.bfd.data = client;
429 client->rem_wq.bfd.when = BSC_FD_READ;
430 client->rem_wq.read_cb = read_cb;
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200431 client->state = STATE_INITIAL;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200432 client->pend = sizeof(*client->data);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200433}
434
435static int accept_cb(struct osmo_fd *fd, unsigned int when)
436{
437 struct osmo_pcap_conn *conn;
438 struct osmo_pcap_server *server;
439 struct sockaddr_in addr;
440 socklen_t size = sizeof(addr);
441 int new_fd;
442
443 new_fd = accept(fd->fd, (struct sockaddr *) &addr, &size);
444 if (new_fd < 0) {
445 LOGP(DSERVER, LOGL_ERROR, "Failed to accept socket: %d\n", errno);
446 return -1;
447 }
448
449 server = fd->data;
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200450
451 /* count any accept to see no clients */
452 rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_CONNECT]);
453
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200454 llist_for_each_entry(conn, &server->conn, entry) {
455 if (conn->remote_addr.s_addr == addr.sin_addr.s_addr) {
456 LOGP(DSERVER, LOGL_NOTICE,
457 "New connection from %s\n", conn->name);
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200458 client_event(conn, "connect", NULL);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200459 new_connection(server, conn, new_fd);
460 return 0;
461 }
462 }
463
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200464 rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_NOCLIENT]);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200465 LOGP(DSERVER, LOGL_ERROR,
466 "Failed to find client for %s\n", inet_ntoa(addr.sin_addr));
467 close(new_fd);
468 return -1;
469}
470
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200471int osmo_pcap_server_listen(struct osmo_pcap_server *server)
472{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200473 int fd;
474
475 fd = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
Daniel Willmannb0003682011-07-17 17:48:19 +0200476 server->addr, server->port, OSMO_SOCK_F_BIND);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200477 if (fd < 0) {
478 LOGP(DSERVER, LOGL_ERROR, "Failed to create the server socket.\n");
479 return -1;
480 }
481
482 server->listen_fd.fd = fd;
483 server->listen_fd.when = BSC_FD_READ;
484 server->listen_fd.cb = accept_cb;
485 server->listen_fd.data = server;
486
487 if (osmo_fd_register(&server->listen_fd) != 0) {
488 LOGP(DSERVER, LOGL_ERROR, "Failed to register the socket.\n");
489 close(fd);
490 return -1;
491 }
492
493 return 0;
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200494}
Daniel Willmannc7401c62011-07-17 17:48:18 +0200495
496void osmo_pcap_server_reopen(struct osmo_pcap_server *server)
497{
498 struct osmo_pcap_conn *conn;
499 LOGP(DSERVER, LOGL_INFO, "Reopening all logfiles.\n");
500 llist_for_each_entry(conn, &server->conn, entry) {
501 /* Write the complete packet out first */
502 if (conn->state == STATE_INITIAL) {
503 restart_pcap(conn);
504 } else {
505 LOGP(DSERVER, LOGL_INFO, "Delaying %s until current packet is complete.\n", conn->name);
506 conn->reopen = 1;
507 }
508 }
509}