blob: 553ad209880a5e15cb02522187c3cc02e86138ee [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 Freyther1bec9d52016-09-06 11:01:50 +0200142void osmo_pcap_server_close_conn(struct osmo_pcap_conn *conn)
143{
144 return close_connection(conn);
145}
146
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200147static void restart_pcap(struct osmo_pcap_conn *conn)
148{
149 time_t now = time(NULL);
150 struct tm *tm = localtime(&now);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200151 int rc;
152
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200153 osmo_pcap_server_close_trace(conn);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200154
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200155 /* omit any storing/creation of the file */
156 if (conn->no_store) {
157 conn->last_write = *tm;
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200158 talloc_free(conn->curr_filename);
159 conn->curr_filename = NULL;
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200160 return;
161 }
162
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200163 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 +0200164 conn->server->base_path, conn->name,
165 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
166 tm->tm_hour, tm->tm_min, tm->tm_sec);
Daniel Willmannde773862011-07-17 17:48:17 +0200167
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200168 if (!conn->curr_filename) {
Daniel Willmannde773862011-07-17 17:48:17 +0200169 LOGP(DSERVER, LOGL_ERROR, "Failed to assemble filename for %s.\n", conn->name);
170 return;
171 }
172
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200173 conn->local_fd = creat(conn->curr_filename, 0440);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200174 if (conn->local_fd < 0) {
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200175 LOGP(DSERVER, LOGL_ERROR, "Failed to file: '%s'\n", conn->curr_filename);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200176 return;
177 }
178
179 rc = write(conn->local_fd, &conn->file_hdr, sizeof(conn->file_hdr));
180 if (rc != sizeof(conn->file_hdr)) {
181 LOGP(DSERVER, LOGL_ERROR, "Failed to write the header: %d\n", errno);
182 close(conn->local_fd);
183 conn->local_fd = -1;
184 return;
185 }
186
187 conn->last_write = *tm;
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200188}
189
190static void link_data(struct osmo_pcap_conn *conn, struct osmo_pcap_data *data)
191{
192 struct pcap_file_header *hdr;
193
194 if (data->len != sizeof(*hdr)) {
195 LOGP(DSERVER, LOGL_ERROR, "The pcap_file_header does not fit.\n");
196 close_connection(conn);
197 return;
198 }
199
200 hdr = (struct pcap_file_header *) &data->data[0];
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200201 if (!conn->no_store && conn->local_fd < 0) {
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200202 conn->file_hdr = *hdr;
203 restart_pcap(conn);
204 } else if (memcmp(&conn->file_hdr, hdr, sizeof(*hdr)) != 0) {
205 conn->file_hdr = *hdr;
206 restart_pcap(conn);
207 }
208}
209
210/*
211 * Check if we are past the limit or on a day change
212 */
213static void write_data(struct osmo_pcap_conn *conn, struct osmo_pcap_data *data)
214{
215 time_t now = time(NULL);
216 struct tm *tm = localtime(&now);
217 int rc;
218
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200219 client_data(conn, data);
220
Holger Hans Peter Freyther28994282016-08-04 16:14:38 +0200221 if (conn->no_store) {
222 conn->last_write = *tm;
223 return;
224 }
225
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200226 if (conn->local_fd < -1) {
227 LOGP(DSERVER, LOGL_ERROR, "No file is open. close connection.\n");
228 close_connection(conn);
229 return;
230 }
231
232 off_t cur = lseek(conn->local_fd, 0, SEEK_CUR);
233 if (cur > conn->server->max_size) {
234 LOGP(DSERVER, LOGL_NOTICE, "Rolling over file for %s\n", conn->name);
235 restart_pcap(conn);
236 } else if (conn->last_write.tm_mday != tm->tm_mday ||
237 conn->last_write.tm_mon != tm->tm_mon ||
238 conn->last_write.tm_year != tm->tm_year) {
239 LOGP(DSERVER, LOGL_NOTICE, "Rolling over file for %s\n", conn->name);
240 restart_pcap(conn);
241 }
242
243 conn->last_write = *tm;
244 rc = write(conn->local_fd, &data->data[0], data->len);
245 if (rc != data->len) {
246 LOGP(DSERVER, LOGL_ERROR, "Failed to write for %s\n", conn->name);
247 close_connection(conn);
248 }
249}
250
251
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200252void osmo_pcap_server_delete(struct osmo_pcap_conn *conn)
253{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200254 close_connection(conn);
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200255 llist_del(&conn->entry);
256 talloc_free(conn);
257}
258
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200259struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
260 const char *name)
261{
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200262 struct rate_ctr_group_desc *desc;
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200263 struct osmo_pcap_conn *conn;
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200264
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200265 llist_for_each_entry(conn, &server->conn, entry) {
266 if (strcmp(conn->name, name) == 0)
267 return conn;
268 }
269
270 conn = talloc_zero(server, struct osmo_pcap_conn);
271 if (!conn) {
272 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200273 "Failed to allocate the connection peer=%s.\n", name);
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200274 return NULL;
275 }
276
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200277 /* a bit nasty. we do not work with ids but names */
278 desc = talloc_zero(conn, struct rate_ctr_group_desc);
279 if (!desc) {
280 LOGP(DSERVER, LOGL_ERROR,
281 "Failed to allocate rate ctr desc peer=%s\n", name);
282 talloc_free(conn);
283 return NULL;
284 }
285 memcpy(desc, &pcap_peer_group_desc, sizeof(pcap_peer_group_desc));
286 desc->group_name_prefix = talloc_asprintf(desc, "pcap.peer.%s", name);
287 if (!desc->group_name_prefix) {
288 LOGP(DSERVER, LOGL_ERROR,
289 "Failed to allocate group name prefix peer=%s\n", name);
290 talloc_free(conn);
291 return NULL;
292 }
293 desc->group_description = talloc_asprintf(desc, "PCAP peer statistics %s", name);
294 if (!desc->group_description) {
295 LOGP(DSERVER, LOGL_ERROR,
296 "Failed to allocate group description peer=%s\n", name);
297 talloc_free(conn);
298 return NULL;
299 }
300
301 conn->ctrg = rate_ctr_group_alloc(desc, desc, 0);
302 if (!conn->ctrg) {
303 LOGP(DSERVER, LOGL_ERROR,
304 "Failed to allocate rate ctr peer=%s\n", name);
305 talloc_free(conn);
306 return NULL;
307 }
308
309
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200310 conn->name = talloc_strdup(conn, name);
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200311 /* we never write */
312 osmo_wqueue_init(&conn->rem_wq, 0);
313 conn->rem_wq.bfd.fd = -1;
Holger Hans Peter Freytherdc3d1dc2011-06-01 16:32:29 +0200314 conn->local_fd = -1;
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200315 conn->server = server;
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200316 conn->data = (struct osmo_pcap_data *) &conn->buf[0];
Holger Hans Peter Freyther9f6127f2011-05-31 22:52:41 +0200317 llist_add_tail(&conn->entry, &server->conn);
318 return conn;
319}
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200320
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200321static int read_cb_initial(struct osmo_fd *fd, struct osmo_pcap_conn *conn)
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200322{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200323 int rc;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200324 rc = read(fd->fd, &conn->buf[sizeof(*conn->data) - conn->pend], conn->pend);
325 if (rc <= 0) {
326 LOGP(DSERVER, LOGL_ERROR,
327 "Too short packet. Got %d, wanted %d\n", rc, conn->data->len);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200328 close_connection(conn);
329 return -1;
330 }
331
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200332 conn->pend -= rc;
333 if (conn->pend < 0) {
334 LOGP(DSERVER, LOGL_ERROR,
335 "Someone got the pending read wrong: %d\n", conn->pend);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200336 close_connection(conn);
337 return -1;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200338 } else if (conn->pend == 0) {
339 conn->data->len = ntohs(conn->data->len);
340
Holger Hans Peter Freytherff1a5dc2015-12-03 19:32:04 +0100341 if (conn->data->len > SERVER_MAX_DATA_SIZE) {
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200342 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther26327bd2015-12-03 19:29:38 +0100343 "Implausible data length: %u\n", conn->data->len);
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200344 close_connection(conn);
345 return -1;
346 }
347
348 conn->state = STATE_DATA;
349 conn->pend = conn->data->len;
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200350 }
351
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200352 return 0;
353}
354
355static int read_cb_data(struct osmo_fd *fd, struct osmo_pcap_conn *conn)
356{
357 int rc;
358 rc = read(fd->fd, &conn->data->data[conn->data->len - conn->pend], conn->pend);
359 if (rc <= 0) {
Holger Hans Peter Freyther59bfb582011-06-01 17:00:12 +0200360 LOGP(DSERVER, LOGL_ERROR,
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200361 "Too short packet. Got %d, wanted %d\n", rc, conn->data->len);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200362 close_connection(conn);
363 return -1;
364 }
365
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200366 conn->pend -= rc;
367 if (conn->pend < 0) {
368 LOGP(DSERVER, LOGL_ERROR,
369 "Someone got the pending read wrong: %d\n", conn->pend);
370 close_connection(conn);
371 return -1;
372 } else if (conn->pend == 0) {
373 conn->state = STATE_INITIAL;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200374 conn->pend = sizeof(*conn->data);
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200375
376 /* count the full packet we got */
377 rate_ctr_inc(&conn->ctrg->ctr[PEER_CTR_PKTS]);
378 rate_ctr_inc(&conn->server->ctrg->ctr[SERVER_CTR_PKTS]);
379
380 /* count the bytes of it */
381 rate_ctr_add(&conn->ctrg->ctr[PEER_CTR_BYTES], conn->data->len);
382 rate_ctr_add(&conn->server->ctrg->ctr[SERVER_CTR_BYTES], conn->data->len);
383
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200384 switch (conn->data->type) {
385 case PKT_LINK_HDR:
386 link_data(conn, conn->data);
387 break;
388 case PKT_LINK_DATA:
389 write_data(conn, conn->data);
390 break;
391 }
392 }
393
394 return 0;
395}
396
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200397static int read_cb(struct osmo_fd *fd)
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200398{
399 struct osmo_pcap_conn *conn;
400
401 conn = fd->data;
402
403 if (conn->state == STATE_INITIAL) {
Daniel Willmannc7401c62011-07-17 17:48:18 +0200404 if (conn->reopen) {
405 LOGP(DSERVER, LOGL_INFO, "Reopening log for %s now.\n", conn->name);
406 restart_pcap(conn);
407 conn->reopen = 0;
408 }
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200409 return read_cb_initial(fd, conn);
410 } else if (conn->state == STATE_DATA) {
411 return read_cb_data(fd, conn);
Holger Hans Peter Freyther7309a902011-06-01 14:04:22 +0200412 }
413
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200414 return 0;
415}
416
417static void new_connection(struct osmo_pcap_server *server,
418 struct osmo_pcap_conn *client, int new_fd)
419{
420 close_connection(client);
421
422 memset(&client->file_hdr, 0, sizeof(client->file_hdr));
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200423 client->rem_wq.bfd.fd = new_fd;
424 if (osmo_fd_register(&client->rem_wq.bfd) != 0) {
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200425 LOGP(DSERVER, LOGL_ERROR, "Failed to register fd.\n");
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200426 client->rem_wq.bfd.fd = -1;
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200427 close(new_fd);
428 return;
429 }
430
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200431 rate_ctr_inc(&client->ctrg->ctr[PEER_CTR_CONNECT]);
432
Holger Hans Peter Freyther098850d2016-08-26 19:31:16 +0200433 client->rem_wq.bfd.data = client;
434 client->rem_wq.bfd.when = BSC_FD_READ;
435 client->rem_wq.read_cb = read_cb;
Holger Hans Peter Freyther39d904f2011-06-01 18:49:07 +0200436 client->state = STATE_INITIAL;
Holger Hans Peter Freyther91eaae32011-06-02 17:58:46 +0200437 client->pend = sizeof(*client->data);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200438}
439
440static int accept_cb(struct osmo_fd *fd, unsigned int when)
441{
442 struct osmo_pcap_conn *conn;
443 struct osmo_pcap_server *server;
444 struct sockaddr_in addr;
445 socklen_t size = sizeof(addr);
446 int new_fd;
447
448 new_fd = accept(fd->fd, (struct sockaddr *) &addr, &size);
449 if (new_fd < 0) {
450 LOGP(DSERVER, LOGL_ERROR, "Failed to accept socket: %d\n", errno);
451 return -1;
452 }
453
454 server = fd->data;
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200455
456 /* count any accept to see no clients */
457 rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_CONNECT]);
458
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200459 llist_for_each_entry(conn, &server->conn, entry) {
460 if (conn->remote_addr.s_addr == addr.sin_addr.s_addr) {
461 LOGP(DSERVER, LOGL_NOTICE,
462 "New connection from %s\n", conn->name);
Holger Hans Peter Freythere0248692016-08-05 15:47:08 +0200463 client_event(conn, "connect", NULL);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200464 new_connection(server, conn, new_fd);
465 return 0;
466 }
467 }
468
Holger Hans Peter Freyther99526a62016-08-19 19:15:39 +0200469 rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_NOCLIENT]);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200470 LOGP(DSERVER, LOGL_ERROR,
471 "Failed to find client for %s\n", inet_ntoa(addr.sin_addr));
472 close(new_fd);
473 return -1;
474}
475
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200476int osmo_pcap_server_listen(struct osmo_pcap_server *server)
477{
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200478 int fd;
479
480 fd = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
Daniel Willmannb0003682011-07-17 17:48:19 +0200481 server->addr, server->port, OSMO_SOCK_F_BIND);
Holger Hans Peter Freyther80b8b602011-05-31 23:42:20 +0200482 if (fd < 0) {
483 LOGP(DSERVER, LOGL_ERROR, "Failed to create the server socket.\n");
484 return -1;
485 }
486
487 server->listen_fd.fd = fd;
488 server->listen_fd.when = BSC_FD_READ;
489 server->listen_fd.cb = accept_cb;
490 server->listen_fd.data = server;
491
492 if (osmo_fd_register(&server->listen_fd) != 0) {
493 LOGP(DSERVER, LOGL_ERROR, "Failed to register the socket.\n");
494 close(fd);
495 return -1;
496 }
497
498 return 0;
Holger Hans Peter Freyther13619dd2011-05-31 22:09:08 +0200499}
Daniel Willmannc7401c62011-07-17 17:48:18 +0200500
501void osmo_pcap_server_reopen(struct osmo_pcap_server *server)
502{
503 struct osmo_pcap_conn *conn;
504 LOGP(DSERVER, LOGL_INFO, "Reopening all logfiles.\n");
505 llist_for_each_entry(conn, &server->conn, entry) {
506 /* Write the complete packet out first */
507 if (conn->state == STATE_INITIAL) {
508 restart_pcap(conn);
509 } else {
510 LOGP(DSERVER, LOGL_INFO, "Delaying %s until current packet is complete.\n", conn->name);
511 conn->reopen = 1;
512 }
513 }
514}