• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14526975710

17 Apr 2025 09:06PM UTC coverage: 72.13% (+0.01%) from 72.117%
14526975710

push

github

yuwata
rules: Make ADB and fastboot work out-of-the-box

https://android.googlesource.com/platform/packages/modules/adb/+/d0db47dcd/adb.h#199
https://android.googlesource.com/platform/system/core/+/7199051aa/fastboot/fastboot.cpp#244

297093 of 411885 relevant lines covered (72.13%)

687643.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.88
/src/resolve/resolved-socket-graveyard.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "resolved-socket-graveyard.h"
4

5
#define SOCKET_GRAVEYARD_USEC (5 * USEC_PER_SEC)
6
#define SOCKET_GRAVEYARD_MAX 100
7

8
/* This implements a socket "graveyard" for UDP sockets. If a socket fd is added to the graveyard it is kept
9
 * open for a couple of more seconds, expecting one reply. Once the reply is received the fd is closed
10
 * immediately, or if none is received it is closed after the timeout. Why all this? So that if we contact a
11
 * DNS server, and it doesn't reply instantly, and we lose interest in the response and thus close the fd, we
12
 * don't end up sending back an ICMP error once the server responds but we aren't listening anymore. (See
13
 * https://github.com/systemd/systemd/issues/17421 for further information.)
14
 *
15
 * Note that we don't allocate any timer event source to clear up the graveyard once the socket's timeout is
16
 * reached. Instead we operate lazily: we close old entries when adding a new fd to the graveyard, or
17
 * whenever any code runs manager_socket_graveyard_process() — which the DNS transaction code does right
18
 * before allocating a new UDP socket. */
19

20
static SocketGraveyard* socket_graveyard_free(SocketGraveyard *g) {
167✔
21
        if (!g)
167✔
22
                return NULL;
23

24
        if (g->manager) {
167✔
25
                assert(g->manager->n_socket_graveyard > 0);
167✔
26
                g->manager->n_socket_graveyard--;
167✔
27

28
                if (g->manager->socket_graveyard_oldest == g)
167✔
29
                        g->manager->socket_graveyard_oldest = g->graveyard_prev;
158✔
30

31
                LIST_REMOVE(graveyard, g->manager->socket_graveyard, g);
167✔
32

33
                assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard);
167✔
34
                assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard_oldest);
167✔
35
        }
36

37
        if (g->io_event_source) {
167✔
38
                log_debug("Closing graveyard socket fd %i", sd_event_source_get_io_fd(g->io_event_source));
167✔
39
                sd_event_source_disable_unref(g->io_event_source);
167✔
40
        }
41

42
        return mfree(g);
167✔
43
}
44

45
DEFINE_TRIVIAL_CLEANUP_FUNC(SocketGraveyard*, socket_graveyard_free);
168✔
46

47
void manager_socket_graveyard_process(Manager *m) {
14,359✔
48
        usec_t n = USEC_INFINITY;
14,359✔
49

50
        assert(m);
14,359✔
51

52
        while (m->socket_graveyard_oldest) {
14,512✔
53
                SocketGraveyard *g = m->socket_graveyard_oldest;
2,274✔
54

55
                if (n == USEC_INFINITY)
2,274✔
56
                        assert_se(sd_event_now(m->event, CLOCK_BOOTTIME, &n) >= 0);
2,178✔
57

58
                if (g->deadline > n)
2,274✔
59
                        break;
60

61
                socket_graveyard_free(g);
153✔
62
        }
63
}
14,359✔
64

65
void manager_socket_graveyard_clear(Manager *m) {
162✔
66
        assert(m);
162✔
67

68
        while (m->socket_graveyard)
176✔
69
                socket_graveyard_free(m->socket_graveyard);
14✔
70
}
162✔
71

72
static int on_io_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
×
73
        SocketGraveyard *g = ASSERT_PTR(userdata);
×
74

75
        /* An IO event happened on the graveyard fd. We don't actually care which event that is, and we don't
76
         * read any incoming packet off the socket. We just close the fd, that's enough to not trigger the
77
         * ICMP unreachable port event */
78

79
        socket_graveyard_free(g);
×
80
        return 0;
×
81
}
82

83
static void manager_socket_graveyard_make_room(Manager *m) {
168✔
84
        assert(m);
168✔
85

86
        while (m->n_socket_graveyard >= SOCKET_GRAVEYARD_MAX)
168✔
87
                socket_graveyard_free(m->socket_graveyard_oldest);
×
88
}
168✔
89

90
int manager_add_socket_to_graveyard(Manager *m, int fd) {
168✔
91
        _cleanup_(socket_graveyard_freep) SocketGraveyard *g = NULL;
168✔
92
        int r;
168✔
93

94
        assert(m);
168✔
95
        assert(fd >= 0);
168✔
96

97
        manager_socket_graveyard_process(m);
168✔
98
        manager_socket_graveyard_make_room(m);
168✔
99

100
        g = new(SocketGraveyard, 1);
168✔
101
        if (!g)
168✔
102
                return log_oom();
×
103

104
        *g = (SocketGraveyard) {
168✔
105
                .manager = m,
106
        };
107

108
        LIST_PREPEND(graveyard, m->socket_graveyard, g);
168✔
109
        if (!m->socket_graveyard_oldest)
168✔
110
                m->socket_graveyard_oldest = g;
63✔
111

112
        m->n_socket_graveyard++;
168✔
113

114
        assert_se(sd_event_now(m->event, CLOCK_BOOTTIME, &g->deadline) >= 0);
168✔
115
        g->deadline += SOCKET_GRAVEYARD_USEC;
168✔
116

117
        r = sd_event_add_io(m->event, &g->io_event_source, fd, EPOLLIN, on_io_event, g);
168✔
118
        if (r < 0)
168✔
119
                return log_error_errno(r, "Failed to create graveyard IO source: %m");
×
120

121
        r = sd_event_source_set_io_fd_own(g->io_event_source, true);
168✔
122
        if (r < 0)
168✔
123
                return log_error_errno(r, "Failed to enable graveyard IO source fd ownership: %m");
×
124

125
        (void) sd_event_source_set_description(g->io_event_source, "graveyard");
168✔
126

127
        log_debug("Added socket %i to graveyard", fd);
168✔
128

129
        TAKE_PTR(g);
168✔
130
        return 0;
168✔
131
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc