1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2014-2015 Timo Teräs
11 #include <sys/socket.h>
19 const char *nhrp_event_socket_path
;
20 struct nhrp_reqid_pool nhrp_event_reqid
;
22 struct event_manager
{
23 struct event
*t_reconnect
, *t_read
, *t_write
;
25 struct zbuf_queue obuf
;
27 uint8_t ibuf_data
[4 * 1024];
30 static void evmgr_reconnect(struct event
*t
);
32 static void evmgr_connection_error(struct event_manager
*evmgr
)
34 EVENT_OFF(evmgr
->t_read
);
35 EVENT_OFF(evmgr
->t_write
);
36 zbuf_reset(&evmgr
->ibuf
);
37 zbufq_reset(&evmgr
->obuf
);
42 if (nhrp_event_socket_path
)
43 event_add_timer_msec(master
, evmgr_reconnect
, evmgr
, 10,
47 static void evmgr_recv_message(struct event_manager
*evmgr
, struct zbuf
*zb
)
52 char buf
[256], result
[64] = "";
54 while (zbuf_may_pull_until(zb
, "\n", &zl
)) {
55 len
= zbuf_used(&zl
) - 1;
56 if (len
>= sizeof(buf
) - 1)
58 memcpy(buf
, zbuf_pulln(&zl
, len
), len
);
61 debugf(NHRP_DEBUG_EVENT
, "evmgr: msg: %s", buf
);
62 if (sscanf(buf
, "eventid=%" SCNu32
, &eventid
) == 1)
64 if (sscanf(buf
, "result=%63s", result
) == 1)
67 debugf(NHRP_DEBUG_EVENT
, "evmgr: received: eventid=%d result=%s",
69 if (eventid
&& result
[0]) {
70 struct nhrp_reqid
*r
=
71 nhrp_reqid_lookup(&nhrp_event_reqid
, eventid
);
77 static void evmgr_read(struct event
*t
)
79 struct event_manager
*evmgr
= EVENT_ARG(t
);
80 struct zbuf
*ibuf
= &evmgr
->ibuf
;
83 if (zbuf_read(ibuf
, evmgr
->fd
, (size_t)-1) < 0) {
84 evmgr_connection_error(evmgr
);
88 /* Process all messages in buffer */
89 while (zbuf_may_pull_until(ibuf
, "\n\n", &msg
))
90 evmgr_recv_message(evmgr
, &msg
);
92 event_add_read(master
, evmgr_read
, evmgr
, evmgr
->fd
, &evmgr
->t_read
);
95 static void evmgr_write(struct event
*t
)
97 struct event_manager
*evmgr
= EVENT_ARG(t
);
100 r
= zbufq_write(&evmgr
->obuf
, evmgr
->fd
);
102 event_add_write(master
, evmgr_write
, evmgr
, evmgr
->fd
,
105 evmgr_connection_error(evmgr
);
109 static void evmgr_hexdump(struct zbuf
*zb
, const uint8_t *val
, size_t vallen
)
111 static const char xd
[] = "0123456789abcdef";
115 ptr
= zbuf_pushn(zb
, 2 * vallen
);
119 for (i
= 0; i
< vallen
; i
++) {
121 *(ptr
++) = xd
[b
>> 4];
122 *(ptr
++) = xd
[b
& 0xf];
126 static void evmgr_put(struct zbuf
*zb
, const char *fmt
, ...)
128 const char *pos
, *nxt
, *str
;
130 const union sockunion
*su
;
135 for (pos
= fmt
; (nxt
= strchr(pos
, '%')) != NULL
; pos
= nxt
+ 2) {
136 zbuf_put(zb
, pos
, nxt
- pos
);
143 snprintf((char *)zb
->tail
, zbuf_tailroom(zb
),
144 "%u", va_arg(va
, uint32_t));
147 str
= va_arg(va
, const char *);
148 zbuf_put(zb
, str
, strlen(str
));
151 su
= va_arg(va
, const union sockunion
*);
152 if (sockunion2str(su
, (char *)zb
->tail
,
154 zb
->tail
+= strlen((char *)zb
->tail
);
159 bin
= va_arg(va
, const uint8_t *);
160 len
= va_arg(va
, int);
161 evmgr_hexdump(zb
, bin
, len
);
166 zbuf_put(zb
, pos
, strlen(pos
));
169 static void evmgr_submit(struct event_manager
*evmgr
, struct zbuf
*obuf
)
175 zbuf_put(obuf
, "\n", 1);
176 zbufq_queue(&evmgr
->obuf
, obuf
);
178 event_add_write(master
, evmgr_write
, evmgr
, evmgr
->fd
,
182 static void evmgr_reconnect(struct event
*t
)
184 struct event_manager
*evmgr
= EVENT_ARG(t
);
187 if (evmgr
->fd
>= 0 || !nhrp_event_socket_path
)
190 fd
= sock_open_unix(nhrp_event_socket_path
);
192 zlog_warn("%s: failure connecting nhrp-event socket: %s",
193 __func__
, strerror(errno
));
194 zbufq_reset(&evmgr
->obuf
);
195 event_add_timer(master
, evmgr_reconnect
, evmgr
, 10,
196 &evmgr
->t_reconnect
);
200 zlog_info("Connected to Event Manager");
202 event_add_read(master
, evmgr_read
, evmgr
, evmgr
->fd
, &evmgr
->t_read
);
205 static struct event_manager evmgr_connection
;
207 void evmgr_init(void)
209 struct event_manager
*evmgr
= &evmgr_connection
;
212 zbuf_init(&evmgr
->ibuf
, evmgr
->ibuf_data
, sizeof(evmgr
->ibuf_data
), 0);
213 zbufq_init(&evmgr
->obuf
);
214 event_add_timer_msec(master
, evmgr_reconnect
, evmgr
, 10,
215 &evmgr
->t_reconnect
);
218 void evmgr_set_socket(const char *socket
)
220 if (nhrp_event_socket_path
) {
221 free((char *)nhrp_event_socket_path
);
222 nhrp_event_socket_path
= NULL
;
225 nhrp_event_socket_path
= strdup(socket
);
226 evmgr_connection_error(&evmgr_connection
);
229 void evmgr_terminate(void)
233 void evmgr_notify(const char *name
, struct nhrp_cache
*c
,
234 void (*cb
)(struct nhrp_reqid
*, void *))
236 struct event_manager
*evmgr
= &evmgr_connection
;
238 struct nhrp_interface
*nifp
= c
->ifp
->info
;
240 afi_t afi
= family2afi(sockunion_family(&c
->remote_addr
));
242 if (!nhrp_event_socket_path
) {
243 cb(&c
->eventid
, (void *)"accept");
247 debugf(NHRP_DEBUG_EVENT
, "evmgr: sending event %s", name
);
249 vc
= c
->new.peer
? c
->new.peer
->vc
: NULL
;
251 1024 + (vc
? (vc
->local
.certlen
+ vc
->remote
.certlen
) * 2 : 0));
254 nhrp_reqid_free(&nhrp_event_reqid
, &c
->eventid
);
255 evmgr_put(zb
, "eventid=%u\n",
256 nhrp_reqid_alloc(&nhrp_event_reqid
, &c
->eventid
, cb
));
266 name
, nhrp_cache_type_str
[c
->new.type
],
267 nhrp_cache_type_str
[c
->cur
.type
],
268 (unsigned int)nhrp_cache_counts
[NHRP_CACHE_NHS
], c
->ifp
->name
,
269 &nifp
->afi
[afi
].addr
);
279 c
->new.peer
->requested
? "yes" : "no",
280 &vc
->local
.nbma
, vc
->local
.cert
, vc
->local
.certlen
,
281 &c
->remote_addr
, &vc
->remote
.nbma
, vc
->remote
.cert
,
285 evmgr_submit(evmgr
, zb
);