blob: 22af2b47e8cbce1b8883f994545afea0c1f0b233 [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 Freyther54ff0b12011-06-01 16:33:11 +0200132 if (conn->rem_fd.fd >= 0) {
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200133 close(conn->rem_fd.fd);
134 conn->rem_fd.fd = -1;
135 osmo_fd_unregister(&conn->rem_fd);
136 }
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);
306 conn->rem_fd.fd = -1;
Holger Hans Peter Freytherdc3d1dc2011-06-01 16:32:29 +0200307 conn->local_fd = -1;
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200308 conn->server = server;
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200309 conn->data = (struct osmo_pcap_data *) &conn->buf[0];
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200310 llist_add_tail(&conn->entry, &server->conn);
311 return conn;
312}
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200313
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200314static int read_cb_initial(struct osmo_fd *fd, struct osmo_pcap_conn *conn)
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200315{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200316 int rc;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200317 rc = read(fd->fd, &conn->buf[sizeof(*conn->data) - conn->pend], conn->pend);
318 if (rc <= 0) {
319 LOGP(DSERVER, LOGL_ERROR,
320 "Too short packet. Got %d, wanted %d\n", rc, conn->data->len);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200321 close_connection(conn);
322 return -1;
323 }
324
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200325 conn->pend -= rc;
326 if (conn->pend < 0) {
327 LOGP(DSERVER, LOGL_ERROR,
328 "Someone got the pending read wrong: %d\n", conn->pend);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200329 close_connection(conn);
330 return -1;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200331 } else if (conn->pend == 0) {
332 conn->data->len = ntohs(conn->data->len);
333
Holger Hans Peter Freytherff1a5dc2015-12-03 19:32:04 +0100334 if (conn->data->len > SERVER_MAX_DATA_SIZE) {
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200335 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther26327bd2015-12-03 19:29:38 +0100336 "Implausible data length: %u\n", conn->data->len);
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200337 close_connection(conn);
338 return -1;
339 }
340
341 conn->state = STATE_DATA;
342 conn->pend = conn->data->len;
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200343 }
344
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200345 return 0;
346}
347
348static int read_cb_data(struct osmo_fd *fd, struct osmo_pcap_conn *conn)
349{
350 int rc;
351 rc = read(fd->fd, &conn->data->data[conn->data->len - conn->pend], conn->pend);
352 if (rc <= 0) {
Holger Hans Peter Freyther59bfb582011-06-01 17:00:12 +0200353 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200354 "Too short packet. Got %d, wanted %d\n", rc, conn->data->len);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200355 close_connection(conn);
356 return -1;
357 }
358
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200359 conn->pend -= rc;
360 if (conn->pend < 0) {
361 LOGP(DSERVER, LOGL_ERROR,
362 "Someone got the pending read wrong: %d\n", conn->pend);
363 close_connection(conn);
364 return -1;
365 } else if (conn->pend == 0) {
366 conn->state = STATE_INITIAL;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200367 conn->pend = sizeof(*conn->data);
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200368
369 /* count the full packet we got */
370 rate_ctr_inc(&conn->ctrg->ctr[PEER_CTR_PKTS]);
371 rate_ctr_inc(&conn->server->ctrg->ctr[SERVER_CTR_PKTS]);
372
373 /* count the bytes of it */
374 rate_ctr_add(&conn->ctrg->ctr[PEER_CTR_BYTES], conn->data->len);
375 rate_ctr_add(&conn->server->ctrg->ctr[SERVER_CTR_BYTES], conn->data->len);
376
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200377 switch (conn->data->type) {
378 case PKT_LINK_HDR:
379 link_data(conn, conn->data);
380 break;
381 case PKT_LINK_DATA:
382 write_data(conn, conn->data);
383 break;
384 }
385 }
386
387 return 0;
388}
389
390static int read_cb(struct osmo_fd *fd, unsigned int what)
391{
392 struct osmo_pcap_conn *conn;
393
394 conn = fd->data;
395
396 if (conn->state == STATE_INITIAL) {
Daniel Willmannc7401c62011-07-17 17:48:18 +0200397 if (conn->reopen) {
398 LOGP(DSERVER, LOGL_INFO, "Reopening log for %s now.\n", conn->name);
399 restart_pcap(conn);
400 conn->reopen = 0;
401 }
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200402 return read_cb_initial(fd, conn);
403 } else if (conn->state == STATE_DATA) {
404 return read_cb_data(fd, conn);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200405 }
406
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200407 return 0;
408}
409
410static void new_connection(struct osmo_pcap_server *server,
411 struct osmo_pcap_conn *client, int new_fd)
412{
413 close_connection(client);
414
415 memset(&client->file_hdr, 0, sizeof(client->file_hdr));
416 client->rem_fd.fd = new_fd;
417 if (osmo_fd_register(&client->rem_fd) != 0) {
418 LOGP(DSERVER, LOGL_ERROR, "Failed to register fd.\n");
419 client->rem_fd.fd = -1;
420 close(new_fd);
421 return;
422 }
423
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200424 rate_ctr_inc(&client->ctrg->ctr[PEER_CTR_CONNECT]);
425
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200426 client->rem_fd.data = client;
427 client->rem_fd.when = BSC_FD_READ;
428 client->rem_fd.cb = read_cb;
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200429 client->state = STATE_INITIAL;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200430 client->pend = sizeof(*client->data);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200431}
432
433static int accept_cb(struct osmo_fd *fd, unsigned int when)
434{
435 struct osmo_pcap_conn *conn;
436 struct osmo_pcap_server *server;
437 struct sockaddr_in addr;
438 socklen_t size = sizeof(addr);
439 int new_fd;
440
441 new_fd = accept(fd->fd, (struct sockaddr *) &addr, &size);
442 if (new_fd < 0) {
443 LOGP(DSERVER, LOGL_ERROR, "Failed to accept socket: %d\n", errno);
444 return -1;
445 }
446
447 server = fd->data;
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200448
449 /* count any accept to see no clients */
450 rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_CONNECT]);
451
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200452 llist_for_each_entry(conn, &server->conn, entry) {
453 if (conn->remote_addr.s_addr == addr.sin_addr.s_addr) {
454 LOGP(DSERVER, LOGL_NOTICE,
455 "New connection from %s\n", conn->name);
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200456 client_event(conn, "connect", NULL);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200457 new_connection(server, conn, new_fd);
458 return 0;
459 }
460 }
461
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200462 rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_NOCLIENT]);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200463 LOGP(DSERVER, LOGL_ERROR,
464 "Failed to find client for %s\n", inet_ntoa(addr.sin_addr));
465 close(new_fd);
466 return -1;
467}
468
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200469int osmo_pcap_server_listen(struct osmo_pcap_server *server)
470{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200471 int fd;
472
473 fd = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
Daniel Willmannb0003682011-07-17 17:48:19 +0200474 server->addr, server->port, OSMO_SOCK_F_BIND);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200475 if (fd < 0) {
476 LOGP(DSERVER, LOGL_ERROR, "Failed to create the server socket.\n");
477 return -1;
478 }
479
480 server->listen_fd.fd = fd;
481 server->listen_fd.when = BSC_FD_READ;
482 server->listen_fd.cb = accept_cb;
483 server->listen_fd.data = server;
484
485 if (osmo_fd_register(&server->listen_fd) != 0) {
486 LOGP(DSERVER, LOGL_ERROR, "Failed to register the socket.\n");
487 close(fd);
488 return -1;
489 }
490
491 return 0;
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200492}
Daniel Willmannc7401c62011-07-17 17:48:18 +0200493
494void osmo_pcap_server_reopen(struct osmo_pcap_server *server)
495{
496 struct osmo_pcap_conn *conn;
497 LOGP(DSERVER, LOGL_INFO, "Reopening all logfiles.\n");
498 llist_for_each_entry(conn, &server->conn, entry) {
499 /* Write the complete packet out first */
500 if (conn->state == STATE_INITIAL) {
501 restart_pcap(conn);
502 } else {
503 LOGP(DSERVER, LOGL_INFO, "Delaying %s until current packet is complete.\n", conn->name);
504 conn->reopen = 1;
505 }
506 }
507}