aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/mslookup/mslookup_client.h
blob: cd0c21f131c257f3344aa24a760db3bbb4c0f979 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/mslookup/mslookup.h>

struct osmo_mslookup_client;
struct osmo_mslookup_result;

typedef void (*osmo_mslookup_cb_t)(struct osmo_mslookup_client *client,
				   uint32_t request_handle,
				   const struct osmo_mslookup_query *query,
				   const struct osmo_mslookup_result *result);

/*! This handling information is passed along with a lookup request.
 * It tells the osmo_mslookup_client layer how to handle responses received from various mslookup methods (at the time
 * of writing only mDNS exists as a method, but the intention is to easily allow adding other methods in the future).
 * This query handling info is not seen by the individual method implementations, to clarify that it is the
 * osmo_mslookup_client layer that takes care of these details. */
struct osmo_mslookup_query_handling {
	/*! Wait at least this long before returning any results.
	 *
	 * If nonzero, result_cb will be called as soon as this delay has elapsed, either with the so far youngest age
	 * result, or with a "not found yet" result. After this delay has elapsed, receiving results will continue
	 * until result_timeout_milliseconds has elapsed.
	 *
	 * If zero, responses are fed to the result_cb right from the start, every time a younger aged result than
	 * before comes in.
	 *
	 * If a result with age == 0 is received, min_wait_milliseconds is ignored, the result is returned immediately
	 * and listening for responses ends.
	 *
	 * Rationale: If a subscriber has recently moved between sites, multiple results will arrive, and the youngest
	 * age wins. It can make sense to wait a minimum time for responses before determining the winning result.
	 *
	 * However, if no result or no valid result has arrived within a short period, the subscriber may be at a site
	 * that is far away or that is currently experiencing high latency. It is thus a good safety net to still
	 * receive results for an extended period of time.
	 *
	 * For some services, it is possible to establish links to every received result, and whichever link succeeds
	 * will be used (for example for SIP calls: first to pick up the call gets connected, the others are dropped
	 * silently).
	 */
	uint32_t min_wait_milliseconds;

	/*! Total time in milliseconds to listen for lookup responses.
	 *
	 * When this timeout elapses, osmo_mslookup_client_request_cancel() is called implicitly; Manually invoking
	 * osmo_mslookup_client_request_cancel() after result_timeout_milliseconds has elapsed is not necessary, but is
	 * still safe to do anyway.
	 *
	 * If zero, min_wait_milliseconds is also used as result_timeout_milliseconds; if that is also zero, a default
	 * timeout value is used.
	 *
	 * If result_timeout_milliseconds <= min_wait_milliseconds, then min_wait_milliseconds is used as
	 * result_timeout_milliseconds, i.e. the timeout triggers as soon as min_wait_milliseconds hits.
	 *
	 * osmo_mslookup_client_request_cancel() can be called any time to end the request.
	 */
	uint32_t result_timeout_milliseconds;

	/*! Invoked every time a result with a younger age than the previous result has arrived.
	 * To stop receiving results before result_timeout_milliseconds has elapsed, call
	 * osmo_mslookup_client_request_cancel().
	 */
	osmo_mslookup_cb_t result_cb;
};

uint32_t osmo_mslookup_client_request(struct osmo_mslookup_client *client,
				      const struct osmo_mslookup_query *query,
				      const struct osmo_mslookup_query_handling *handling);

void osmo_mslookup_client_request_cancel(struct osmo_mslookup_client *client, uint32_t request_handle);

struct osmo_mslookup_client *osmo_mslookup_client_new(void *ctx);
bool osmo_mslookup_client_active(struct osmo_mslookup_client *client);
void osmo_mslookup_client_free(struct osmo_mslookup_client *client);

/*! Describe a specific mslookup client method implementation. This struct is only useful for a lookup method
 * implementation to add itself to an osmo_mslookup_client, see for example osmo_mslookup_client_add_mdns(). */
struct osmo_mslookup_client_method {
	struct llist_head entry;

	/*! Human readable name of this lookup method. */
	const char *name;

	/*! Private data for the lookup method implementation. */
	void *priv;

	/*! Backpointer to the client this method is added to. */
	struct osmo_mslookup_client *client;

	/*! Launch a lookup query. Called from osmo_mslookup_client_request().
	 * The implementation returns results by calling osmo_mslookup_client_rx_result(). */
	void (*request)(struct osmo_mslookup_client_method *method,
			const struct osmo_mslookup_query *query,
			uint32_t request_handle);
	/*! End a lookup query. Called from osmo_mslookup_client_request_cancel(). It is guaranteed to be called
	 * exactly once per above request() invocation. (The API user is required to invoke
	 * osmo_mslookup_client_request_cancel() exactly once per osmo_mslookup_client_request().) */
	void (*request_cleanup)(struct osmo_mslookup_client_method *method,
				uint32_t request_handle);

	/*! The mslookup_client is removing this method, clean up all open requests, lists and allocations. */
	void (*destruct)(struct osmo_mslookup_client_method *method);
};

void osmo_mslookup_client_method_add(struct osmo_mslookup_client *client,
				     struct osmo_mslookup_client_method *method);
bool osmo_mslookup_client_method_del(struct osmo_mslookup_client *client,
				     struct osmo_mslookup_client_method *method);
void osmo_mslookup_client_rx_result(struct osmo_mslookup_client *client, uint32_t request_handle,
				    const struct osmo_mslookup_result *result);