]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
fdfccdbc ZJS |
2 | |
3 | #include <errno.h> | |
4 | #include <fcntl.h> | |
fdfccdbc | 5 | #include <stdlib.h> |
fdfccdbc | 6 | #include <sys/prctl.h> |
5e38eb93 | 7 | #include <stdint.h> |
3f6fd1ba | 8 | |
fdfccdbc | 9 | #include "sd-daemon.h" |
3f6fd1ba | 10 | |
a4817536 | 11 | #include "af-list.h" |
b5efdb8a | 12 | #include "alloc-util.h" |
28db6fbf | 13 | #include "constants.h" |
4ff9bc2e | 14 | #include "errno-util.h" |
4f5dd394 | 15 | #include "escape.h" |
3ffd4af2 | 16 | #include "fd-util.h" |
1e094703 | 17 | #include "journal-file-util.h" |
4f5dd394 | 18 | #include "journal-remote-write.h" |
3ffd4af2 | 19 | #include "journal-remote.h" |
fdfccdbc | 20 | #include "macro.h" |
6bedfcbb | 21 | #include "parse-util.h" |
d7085bcc | 22 | #include "parse-helpers.h" |
dccca82b | 23 | #include "process-util.h" |
3f6fd1ba | 24 | #include "socket-util.h" |
15a5e950 | 25 | #include "stdio-util.h" |
07630cea | 26 | #include "string-util.h" |
fdfccdbc | 27 | #include "strv.h" |
fdfccdbc | 28 | |
8201af08 | 29 | #define REMOTE_JOURNAL_PATH "/var/log/journal/remote" |
fdfccdbc | 30 | |
9ff48d09 | 31 | #define filename_escape(s) xescape((s), "/ ") |
8201af08 | 32 | |
3c67c8bd FS |
33 | #if HAVE_MICROHTTPD |
34 | MHDDaemonWrapper *MHDDaemonWrapper_free(MHDDaemonWrapper *d) { | |
35 | if (!d) | |
36 | return NULL; | |
37 | ||
38 | if (d->daemon) | |
39 | MHD_stop_daemon(d->daemon); | |
40 | sd_event_source_unref(d->io_event); | |
41 | sd_event_source_unref(d->timer_event); | |
42 | ||
43 | return mfree(d); | |
44 | } | |
45 | #endif | |
46 | ||
c064d8db ZJS |
47 | static int open_output(RemoteServer *s, Writer *w, const char* host) { |
48 | _cleanup_free_ char *_filename = NULL; | |
49 | const char *filename; | |
fdfccdbc ZJS |
50 | int r; |
51 | ||
84a6c2ba FS |
52 | assert(s); |
53 | assert(w); | |
54 | ||
c064d8db | 55 | switch (s->split_mode) { |
8201af08 | 56 | case JOURNAL_WRITE_SPLIT_NONE: |
c064d8db | 57 | filename = s->output; |
8201af08 | 58 | break; |
fdfccdbc | 59 | |
8201af08 | 60 | case JOURNAL_WRITE_SPLIT_HOST: { |
c2b2df60 | 61 | _cleanup_free_ char *name = NULL; |
fdfccdbc | 62 | |
8201af08 | 63 | assert(host); |
fdfccdbc | 64 | |
8201af08 ZJS |
65 | name = filename_escape(host); |
66 | if (!name) | |
67 | return log_oom(); | |
68 | ||
c064d8db | 69 | r = asprintf(&_filename, "%s/remote-%s.journal", s->output, name); |
fdfccdbc ZJS |
70 | if (r < 0) |
71 | return log_oom(); | |
8201af08 | 72 | |
c064d8db | 73 | filename = _filename; |
8201af08 ZJS |
74 | break; |
75 | } | |
76 | ||
77 | default: | |
04499a70 | 78 | assert_not_reached(); |
fdfccdbc ZJS |
79 | } |
80 | ||
45c0ecba | 81 | r = journal_file_open_reliably( |
49615dbd LP |
82 | filename, |
83 | O_RDWR|O_CREAT, | |
84 | s->file_flags, | |
85 | 0640, | |
86 | UINT64_MAX, | |
87 | &w->metrics, | |
88 | w->mmap, | |
89 | NULL, | |
49615dbd | 90 | &w->journal); |
fdfccdbc | 91 | if (r < 0) |
c064d8db ZJS |
92 | return log_error_errno(r, "Failed to open output journal %s: %m", filename); |
93 | ||
45c0ecba | 94 | log_debug("Opened output file %s", w->journal->path); |
c064d8db | 95 | return 0; |
fdfccdbc ZJS |
96 | } |
97 | ||
cc64d017 ZJS |
98 | /********************************************************************** |
99 | ********************************************************************** | |
100 | **********************************************************************/ | |
101 | ||
9ff48d09 | 102 | static int init_writer_hashmap(RemoteServer *s) { |
c064d8db | 103 | static const struct hash_ops* const hash_ops[] = { |
d5099efc MS |
104 | [JOURNAL_WRITE_SPLIT_NONE] = NULL, |
105 | [JOURNAL_WRITE_SPLIT_HOST] = &string_hash_ops, | |
9ff48d09 ZJS |
106 | }; |
107 | ||
c064d8db ZJS |
108 | assert(s); |
109 | assert(s->split_mode >= 0 && s->split_mode < (int) ELEMENTSOF(hash_ops)); | |
cc64d017 | 110 | |
c064d8db | 111 | s->writers = hashmap_new(hash_ops[s->split_mode]); |
9ff48d09 ZJS |
112 | if (!s->writers) |
113 | return log_oom(); | |
114 | ||
115 | return 0; | |
116 | } | |
117 | ||
c064d8db | 118 | int journal_remote_get_writer(RemoteServer *s, const char *host, Writer **writer) { |
8e766630 | 119 | _cleanup_(writer_unrefp) Writer *w = NULL; |
9ff48d09 | 120 | const void *key; |
9ff48d09 ZJS |
121 | int r; |
122 | ||
84a6c2ba FS |
123 | assert(s); |
124 | assert(writer); | |
125 | ||
79893116 | 126 | switch (s->split_mode) { |
9ff48d09 ZJS |
127 | case JOURNAL_WRITE_SPLIT_NONE: |
128 | key = "one and only"; | |
129 | break; | |
130 | ||
131 | case JOURNAL_WRITE_SPLIT_HOST: | |
132 | assert(host); | |
133 | key = host; | |
134 | break; | |
135 | ||
136 | default: | |
04499a70 | 137 | assert_not_reached(); |
9ff48d09 ZJS |
138 | } |
139 | ||
140 | w = hashmap_get(s->writers, key); | |
141 | if (w) | |
142 | writer_ref(w); | |
143 | else { | |
4c3d2523 YW |
144 | r = writer_new(s, &w); |
145 | if (r < 0) | |
146 | return r; | |
9ff48d09 | 147 | |
c064d8db | 148 | if (s->split_mode == JOURNAL_WRITE_SPLIT_HOST) { |
9ff48d09 ZJS |
149 | w->hashmap_key = strdup(key); |
150 | if (!w->hashmap_key) | |
4c3d2523 | 151 | return -ENOMEM; |
9ff48d09 | 152 | } |
cc64d017 | 153 | |
c064d8db | 154 | r = open_output(s, w, host); |
9ff48d09 ZJS |
155 | if (r < 0) |
156 | return r; | |
fdfccdbc | 157 | |
9ff48d09 ZJS |
158 | r = hashmap_put(s->writers, w->hashmap_key ?: key, w); |
159 | if (r < 0) | |
160 | return r; | |
161 | } | |
fdfccdbc | 162 | |
1cc6c93a | 163 | *writer = TAKE_PTR(w); |
9ff48d09 ZJS |
164 | return 0; |
165 | } | |
cc64d017 | 166 | |
9ff48d09 ZJS |
167 | /********************************************************************** |
168 | ********************************************************************** | |
169 | **********************************************************************/ | |
fdfccdbc | 170 | |
e503019b | 171 | /* This should go away as soon as μhttpd allows state to be passed around. */ |
c064d8db | 172 | RemoteServer *journal_remote_server_global; |
cc64d017 | 173 | |
fdfccdbc ZJS |
174 | static int dispatch_raw_source_event(sd_event_source *event, |
175 | int fd, | |
176 | uint32_t revents, | |
177 | void *userdata); | |
043945b9 ZJS |
178 | static int dispatch_raw_source_until_block(sd_event_source *event, |
179 | void *userdata); | |
70f1b2dd ZJS |
180 | static int dispatch_blocking_source_event(sd_event_source *event, |
181 | void *userdata); | |
fdfccdbc ZJS |
182 | static int dispatch_raw_connection_event(sd_event_source *event, |
183 | int fd, | |
184 | uint32_t revents, | |
185 | void *userdata); | |
186 | ||
9ff48d09 ZJS |
187 | static int get_source_for_fd(RemoteServer *s, |
188 | int fd, char *name, RemoteSource **source) { | |
189 | Writer *writer; | |
190 | int r; | |
191 | ||
1f8af042 ZJS |
192 | /* This takes ownership of name, but only on success. */ |
193 | ||
84a6c2ba | 194 | assert(s); |
fdfccdbc ZJS |
195 | assert(fd >= 0); |
196 | assert(source); | |
197 | ||
319a4f4b | 198 | if (!GREEDY_REALLOC0(s->sources, fd + 1)) |
fdfccdbc ZJS |
199 | return log_oom(); |
200 | ||
c064d8db | 201 | r = journal_remote_get_writer(s, name, &writer); |
eb56eb9b MS |
202 | if (r < 0) |
203 | return log_warning_errno(r, "Failed to get writer for source %s: %m", | |
204 | name); | |
9ff48d09 | 205 | |
4e361acc | 206 | if (!s->sources[fd]) { |
9ff48d09 ZJS |
207 | s->sources[fd] = source_new(fd, false, name, writer); |
208 | if (!s->sources[fd]) { | |
209 | writer_unref(writer); | |
fdfccdbc | 210 | return log_oom(); |
9ff48d09 ZJS |
211 | } |
212 | ||
fdfccdbc ZJS |
213 | s->active++; |
214 | } | |
215 | ||
216 | *source = s->sources[fd]; | |
217 | return 0; | |
218 | } | |
219 | ||
220 | static int remove_source(RemoteServer *s, int fd) { | |
221 | RemoteSource *source; | |
222 | ||
223 | assert(s); | |
319a4f4b | 224 | assert(fd >= 0 && fd < (ssize_t) MALLOC_ELEMENTSOF(s->sources)); |
fdfccdbc ZJS |
225 | |
226 | source = s->sources[fd]; | |
227 | if (source) { | |
8201af08 | 228 | /* this closes fd too */ |
fdfccdbc ZJS |
229 | source_free(source); |
230 | s->sources[fd] = NULL; | |
231 | s->active--; | |
232 | } | |
233 | ||
fdfccdbc ZJS |
234 | return 0; |
235 | } | |
236 | ||
c064d8db | 237 | int journal_remote_add_source(RemoteServer *s, int fd, char* name, bool own_name) { |
a7f7d1bd | 238 | RemoteSource *source = NULL; |
fdfccdbc ZJS |
239 | int r; |
240 | ||
1f8af042 ZJS |
241 | /* This takes ownership of name, even on failure, if own_name is true. */ |
242 | ||
fdfccdbc ZJS |
243 | assert(s); |
244 | assert(fd >= 0); | |
9ff48d09 | 245 | assert(name); |
fdfccdbc | 246 | |
9ff48d09 ZJS |
247 | if (!own_name) { |
248 | name = strdup(name); | |
249 | if (!name) | |
250 | return log_oom(); | |
251 | } | |
fdfccdbc | 252 | |
9ff48d09 | 253 | r = get_source_for_fd(s, fd, name, &source); |
fdfccdbc | 254 | if (r < 0) { |
c33b3297 MS |
255 | log_error_errno(r, "Failed to create source for fd:%d (%s): %m", |
256 | fd, name); | |
1f8af042 | 257 | free(name); |
fdfccdbc ZJS |
258 | return r; |
259 | } | |
8201af08 | 260 | |
fdfccdbc | 261 | r = sd_event_add_io(s->events, &source->event, |
8201af08 | 262 | fd, EPOLLIN|EPOLLRDHUP|EPOLLPRI, |
043945b9 ZJS |
263 | dispatch_raw_source_event, source); |
264 | if (r == 0) { | |
265 | /* Add additional source for buffer processing. It will be | |
266 | * enabled later. */ | |
267 | r = sd_event_add_defer(s->events, &source->buffer_event, | |
268 | dispatch_raw_source_until_block, source); | |
269 | if (r == 0) | |
c3c50474 | 270 | r = sd_event_source_set_enabled(source->buffer_event, SD_EVENT_OFF); |
043945b9 | 271 | } else if (r == -EPERM) { |
70f1b2dd ZJS |
272 | log_debug("Falling back to sd_event_add_defer for fd:%d (%s)", fd, name); |
273 | r = sd_event_add_defer(s->events, &source->event, | |
274 | dispatch_blocking_source_event, source); | |
275 | if (r == 0) | |
c3c50474 | 276 | r = sd_event_source_set_enabled(source->event, SD_EVENT_ON); |
70f1b2dd | 277 | } |
fdfccdbc | 278 | if (r < 0) { |
c33b3297 MS |
279 | log_error_errno(r, "Failed to register event source for fd:%d: %m", |
280 | fd); | |
fdfccdbc ZJS |
281 | goto error; |
282 | } | |
283 | ||
356779df | 284 | r = sd_event_source_set_description(source->event, name); |
43300d9d | 285 | if (r < 0) { |
da927ba9 | 286 | log_error_errno(r, "Failed to set source name for fd:%d: %m", fd); |
43300d9d ZJS |
287 | goto error; |
288 | } | |
289 | ||
fdfccdbc ZJS |
290 | return 1; /* work to do */ |
291 | ||
292 | error: | |
293 | remove_source(s, fd); | |
294 | return r; | |
295 | } | |
296 | ||
c064d8db | 297 | int journal_remote_add_raw_socket(RemoteServer *s, int fd) { |
d7ac0952 | 298 | _unused_ _cleanup_close_ int fd_ = fd; |
fbd0b64f | 299 | char name[STRLEN("raw-socket-") + DECIMAL_STR_MAX(int) + 1]; |
84a6c2ba | 300 | int r; |
43300d9d | 301 | |
84a6c2ba | 302 | assert(s); |
43300d9d | 303 | assert(fd >= 0); |
fdfccdbc | 304 | |
8201af08 ZJS |
305 | r = sd_event_add_io(s->events, &s->listen_event, |
306 | fd, EPOLLIN, | |
fdfccdbc | 307 | dispatch_raw_connection_event, s); |
43300d9d | 308 | if (r < 0) |
fdfccdbc | 309 | return r; |
fdfccdbc | 310 | |
5ffa8c81 | 311 | xsprintf(name, "raw-socket-%d", fd); |
43300d9d | 312 | |
356779df | 313 | r = sd_event_source_set_description(s->listen_event, name); |
43300d9d ZJS |
314 | if (r < 0) |
315 | return r; | |
316 | ||
84a6c2ba | 317 | TAKE_FD(fd_); |
313cefa1 | 318 | s->active++; |
fdfccdbc ZJS |
319 | return 0; |
320 | } | |
321 | ||
8201af08 ZJS |
322 | /********************************************************************** |
323 | ********************************************************************** | |
324 | **********************************************************************/ | |
325 | ||
c064d8db ZJS |
326 | int journal_remote_server_init( |
327 | RemoteServer *s, | |
328 | const char *output, | |
329 | JournalWriteSplitMode split_mode, | |
49615dbd | 330 | JournalFileFlags file_flags) { |
cc64d017 | 331 | |
fdfccdbc ZJS |
332 | int r; |
333 | ||
334 | assert(s); | |
335 | ||
c064d8db ZJS |
336 | assert(journal_remote_server_global == NULL); |
337 | journal_remote_server_global = s; | |
fdfccdbc | 338 | |
c064d8db | 339 | s->split_mode = split_mode; |
49615dbd | 340 | s->file_flags = file_flags; |
43300d9d | 341 | |
c064d8db ZJS |
342 | if (output) |
343 | s->output = output; | |
344 | else if (split_mode == JOURNAL_WRITE_SPLIT_NONE) | |
345 | s->output = REMOTE_JOURNAL_PATH "/remote.journal"; | |
346 | else if (split_mode == JOURNAL_WRITE_SPLIT_HOST) | |
347 | s->output = REMOTE_JOURNAL_PATH; | |
42b6bf75 | 348 | else |
04499a70 | 349 | assert_not_reached(); |
ad95fd1d | 350 | |
b1604b34 | 351 | r = sd_event_default(&s->events); |
23bbb0de MS |
352 | if (r < 0) |
353 | return log_error_errno(r, "Failed to allocate event loop: %m"); | |
fdfccdbc | 354 | |
22259a00 JL |
355 | r = init_writer_hashmap(s); |
356 | if (r < 0) | |
357 | return r; | |
358 | ||
8201af08 | 359 | return 0; |
fdfccdbc ZJS |
360 | } |
361 | ||
94952201 | 362 | void journal_remote_server_destroy(RemoteServer *s) { |
ca2d3784 | 363 | size_t i; |
cc64d017 | 364 | |
84a6c2ba FS |
365 | if (!s) |
366 | return; | |
367 | ||
63e2ebcd | 368 | #if HAVE_MICROHTTPD |
1599f593 | 369 | hashmap_free_with_destructor(s->daemons, MHDDaemonWrapper_free); |
63e2ebcd | 370 | #endif |
cc64d017 | 371 | |
319a4f4b | 372 | for (i = 0; i < MALLOC_ELEMENTSOF(s->sources); i++) |
fdfccdbc | 373 | remove_source(s, i); |
fdfccdbc ZJS |
374 | free(s->sources); |
375 | ||
9ff48d09 ZJS |
376 | writer_unref(s->_single_writer); |
377 | hashmap_free(s->writers); | |
378 | ||
fdfccdbc ZJS |
379 | sd_event_source_unref(s->sigterm_event); |
380 | sd_event_source_unref(s->sigint_event); | |
381 | sd_event_source_unref(s->listen_event); | |
382 | sd_event_unref(s->events); | |
383 | ||
c064d8db ZJS |
384 | if (s == journal_remote_server_global) |
385 | journal_remote_server_global = NULL; | |
386 | ||
fdfccdbc | 387 | /* fds that we're listening on remain open... */ |
fdfccdbc ZJS |
388 | } |
389 | ||
390 | /********************************************************************** | |
391 | ********************************************************************** | |
392 | **********************************************************************/ | |
393 | ||
864876ec ZJS |
394 | int journal_remote_handle_raw_source( |
395 | sd_event_source *event, | |
396 | int fd, | |
397 | uint32_t revents, | |
398 | RemoteServer *s) { | |
fdfccdbc | 399 | |
fdfccdbc ZJS |
400 | RemoteSource *source; |
401 | int r; | |
402 | ||
043945b9 ZJS |
403 | /* Returns 1 if there might be more data pending, |
404 | * 0 if data is currently exhausted, negative on error. | |
405 | */ | |
406 | ||
84a6c2ba | 407 | assert(s); |
319a4f4b | 408 | assert(fd >= 0 && fd < (ssize_t) MALLOC_ELEMENTSOF(s->sources)); |
fdfccdbc | 409 | source = s->sources[fd]; |
b18453ed | 410 | assert(source->importer.fd == fd); |
fdfccdbc | 411 | |
49615dbd | 412 | r = process_source(source, s->file_flags); |
b18453ed | 413 | if (journal_importer_eof(&source->importer)) { |
4a0a6ac0 ZJS |
414 | size_t remaining; |
415 | ||
b18453ed ZJS |
416 | log_debug("EOF reached with source %s (fd=%d)", |
417 | source->importer.name, source->importer.fd); | |
4a0a6ac0 | 418 | |
b18453ed | 419 | remaining = journal_importer_bytes_remaining(&source->importer); |
4a0a6ac0 | 420 | if (remaining > 0) |
0e72da6f | 421 | log_notice("Premature EOF. %zu bytes lost.", remaining); |
b18453ed | 422 | remove_source(s, source->importer.fd); |
0e72da6f | 423 | log_debug("%zu active sources remaining", s->active); |
8201af08 | 424 | return 0; |
fdfccdbc | 425 | } else if (r == -E2BIG) { |
ef4d6abe ZJS |
426 | log_notice("Entry with too many fields, skipped"); |
427 | return 1; | |
428 | } else if (r == -ENOBUFS) { | |
d4e98880 | 429 | log_notice("Entry too big, skipped"); |
8201af08 | 430 | return 1; |
ff55c3c7 | 431 | } else if (r == -EAGAIN) { |
8201af08 ZJS |
432 | return 0; |
433 | } else if (r < 0) { | |
0e72da6f | 434 | log_debug_errno(r, "Closing connection: %m"); |
c064d8db | 435 | remove_source(s, fd); |
8201af08 ZJS |
436 | return 0; |
437 | } else | |
438 | return 1; | |
fdfccdbc ZJS |
439 | } |
440 | ||
043945b9 ZJS |
441 | static int dispatch_raw_source_until_block(sd_event_source *event, |
442 | void *userdata) { | |
84a6c2ba | 443 | RemoteSource *source = ASSERT_PTR(userdata); |
043945b9 ZJS |
444 | int r; |
445 | ||
84a6c2ba FS |
446 | assert(event); |
447 | ||
043945b9 ZJS |
448 | /* Make sure event stays around even if source is destroyed */ |
449 | sd_event_source_ref(event); | |
450 | ||
864876ec | 451 | r = journal_remote_handle_raw_source(event, source->importer.fd, EPOLLIN, journal_remote_server_global); |
25bb459e LB |
452 | if (r != 1) { |
453 | int k; | |
454 | ||
043945b9 | 455 | /* No more data for now */ |
25bb459e LB |
456 | k = sd_event_source_set_enabled(event, SD_EVENT_OFF); |
457 | if (k < 0) | |
458 | r = k; | |
459 | } | |
043945b9 ZJS |
460 | |
461 | sd_event_source_unref(event); | |
462 | ||
463 | return r; | |
464 | } | |
465 | ||
466 | static int dispatch_raw_source_event(sd_event_source *event, | |
467 | int fd, | |
468 | uint32_t revents, | |
469 | void *userdata) { | |
84a6c2ba | 470 | RemoteSource *source = ASSERT_PTR(userdata); |
043945b9 ZJS |
471 | int r; |
472 | ||
473 | assert(source->event); | |
474 | assert(source->buffer_event); | |
475 | ||
864876ec | 476 | r = journal_remote_handle_raw_source(event, fd, EPOLLIN, journal_remote_server_global); |
25bb459e LB |
477 | if (r == 1) { |
478 | int k; | |
479 | ||
043945b9 ZJS |
480 | /* Might have more data. We need to rerun the handler |
481 | * until we are sure the buffer is exhausted. */ | |
25bb459e LB |
482 | k = sd_event_source_set_enabled(source->buffer_event, SD_EVENT_ON); |
483 | if (k < 0) | |
484 | r = k; | |
485 | } | |
043945b9 ZJS |
486 | |
487 | return r; | |
488 | } | |
489 | ||
70f1b2dd ZJS |
490 | static int dispatch_blocking_source_event(sd_event_source *event, |
491 | void *userdata) { | |
84a6c2ba | 492 | RemoteSource *source = ASSERT_PTR(userdata); |
70f1b2dd | 493 | |
864876ec | 494 | return journal_remote_handle_raw_source(event, source->importer.fd, EPOLLIN, journal_remote_server_global); |
70f1b2dd ZJS |
495 | } |
496 | ||
4ff9bc2e LP |
497 | static int accept_connection( |
498 | const char* type, | |
499 | int fd, | |
500 | SocketAddress *addr, | |
501 | char **hostname) { | |
502 | ||
254d1313 | 503 | _cleanup_close_ int fd2 = -EBADF; |
4ff9bc2e | 504 | int r; |
fdfccdbc | 505 | |
84a6c2ba FS |
506 | assert(addr); |
507 | assert(hostname); | |
508 | ||
cc64d017 ZJS |
509 | log_debug("Accepting new %s connection on fd:%d", type, fd); |
510 | fd2 = accept4(fd, &addr->sockaddr.sa, &addr->size, SOCK_NONBLOCK|SOCK_CLOEXEC); | |
4ff9bc2e LP |
511 | if (fd2 < 0) { |
512 | if (ERRNO_IS_ACCEPT_AGAIN(errno)) | |
513 | return -EAGAIN; | |
514 | ||
4a62c710 | 515 | return log_error_errno(errno, "accept() on fd:%d failed: %m", fd); |
4ff9bc2e | 516 | } |
fdfccdbc | 517 | |
79893116 | 518 | switch (socket_address_family(addr)) { |
fdfccdbc ZJS |
519 | case AF_INET: |
520 | case AF_INET6: { | |
8201af08 ZJS |
521 | _cleanup_free_ char *a = NULL; |
522 | char *b; | |
fdfccdbc | 523 | |
cc64d017 | 524 | r = socket_address_print(addr, &a); |
4ff9bc2e LP |
525 | if (r < 0) |
526 | return log_error_errno(r, "socket_address_print(): %m"); | |
fdfccdbc | 527 | |
fc1f05eb | 528 | r = socknameinfo_pretty(&addr->sockaddr.sa, addr->size, &b); |
4ff9bc2e LP |
529 | if (r < 0) |
530 | return log_error_errno(r, "Resolving hostname failed: %m"); | |
8201af08 | 531 | |
0e72da6f ZJS |
532 | log_debug("Accepted %s %s connection from %s", |
533 | type, | |
a4817536 | 534 | af_to_ipv4_ipv6(socket_address_family(addr)), |
0e72da6f | 535 | a); |
cc64d017 | 536 | |
8201af08 | 537 | *hostname = b; |
4ff9bc2e LP |
538 | return TAKE_FD(fd2); |
539 | } | |
8201af08 | 540 | |
fdfccdbc | 541 | default: |
4ff9bc2e LP |
542 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), |
543 | "Rejected %s connection with unsupported family %d", | |
544 | type, socket_address_family(addr)); | |
fdfccdbc | 545 | } |
cc64d017 | 546 | } |
fdfccdbc | 547 | |
4ff9bc2e LP |
548 | static int dispatch_raw_connection_event( |
549 | sd_event_source *event, | |
550 | int fd, | |
551 | uint32_t revents, | |
552 | void *userdata) { | |
553 | ||
84a6c2ba | 554 | RemoteServer *s = ASSERT_PTR(userdata); |
1f8af042 | 555 | int fd2; |
cc64d017 ZJS |
556 | SocketAddress addr = { |
557 | .size = sizeof(union sockaddr_union), | |
558 | .type = SOCK_STREAM, | |
559 | }; | |
a7f7d1bd | 560 | char *hostname = NULL; |
fdfccdbc | 561 | |
8201af08 | 562 | fd2 = accept_connection("raw", fd, &addr, &hostname); |
4ff9bc2e LP |
563 | if (fd2 == -EAGAIN) |
564 | return 0; | |
cc64d017 ZJS |
565 | if (fd2 < 0) |
566 | return fd2; | |
fdfccdbc | 567 | |
c064d8db | 568 | return journal_remote_add_source(s, fd2, hostname, true); |
fdfccdbc | 569 | } |