Skip to content

Commit 1199d22

Browse files
authored
Introduce NTATAG_INTERCEPT_QUERY_RESULTS and NUTAG_INTERCEPT_QUERY_RESULTS tags. (#290)
* Introduce NTATAG_INTERCEPT_QUERY_RESULTS and NUTAG_INTERCEPT_QUERY_RESULTS tags. * Fix typo
1 parent b298087 commit 1199d22

File tree

12 files changed

+220
-0
lines changed

12 files changed

+220
-0
lines changed

libsofia-sip-ua/nta/nta.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ struct nta_outgoing_s
498498
nta_agent_t *orq_agent;
499499
nta_response_f *orq_callback;
500500
nta_outgoing_magic_t *orq_magic;
501+
nta_outgoing_query_results_data_t *orq_query_results;
501502

502503
/* Timeout/state queue */
503504
nta_outgoing_t **orq_prev;
@@ -533,6 +534,8 @@ struct nta_outgoing_s
533534
unsigned short orq_status;
534535
unsigned char orq_retries; /**< Number of tries this far */
535536

537+
const void *orq_intercept_query_results; /** May become nua_handle_t */
538+
536539
unsigned orq_default:1; /**< This is default transaction */
537540
unsigned orq_inserted:1;
538541
unsigned orq_resolved:1;
@@ -600,6 +603,14 @@ ntatag_delay_sending_ref, tag_bool_vr(&(x))
600603
extern tag_typedef_t ntatag_delay_sending;
601604
extern tag_typedef_t ntatag_delay_sending_ref;
602605

606+
/* Intercept query results */
607+
#define NTATAG_INTERCEPT_QUERY_RESULTS(x) ntatag_intercept_query_results, tag_ptr_v((x))
608+
#define NTATAG_INTERCEPT_QUERY_RESULTS_REF(x) \
609+
ntatag_intercept_query_results_ref, tag_ptr_vr(&(x))
610+
611+
extern tag_typedef_t ntatag_intercept_query_results;
612+
extern tag_typedef_t ntatag_intercept_query_results_ref;
613+
603614
/* Allow sending incomplete responses */
604615
#define NTATAG_INCOMPLETE(x) ntatag_incomplete, tag_bool_v((x))
605616
#define NTATAG_INCOMPLETE_REF(x) \
@@ -7817,6 +7828,29 @@ unsigned nta_outgoing_delay(nta_outgoing_t const *orq)
78177828
return orq != NULL && orq != NONE ? orq->orq_delay : UINT_MAX;
78187829
}
78197830

7831+
/** Get the nta_outgoing_query_results_t */
7832+
nta_outgoing_query_results_data_t *nta_outgoing_query_results(nta_outgoing_t const *orq, char ***results, size_t *found)
7833+
{
7834+
if (orq != NULL && orq != NONE) {
7835+
if (orq->orq_query_results && results && found) {
7836+
*results = orq->orq_query_results->results;
7837+
*found = orq->orq_query_results->found;
7838+
}
7839+
7840+
return orq->orq_query_results;
7841+
} else return NULL;
7842+
}
7843+
7844+
char const *nta_outgoing_cannon(nta_outgoing_t const *orq)
7845+
{
7846+
return orq != NULL && orq != NONE ? orq->orq_tpn[0].tpn_canon : NULL;
7847+
}
7848+
7849+
char const *nta_outgoing_host(nta_outgoing_t const *orq)
7850+
{
7851+
return orq != NULL && orq != NONE ? orq->orq_tpn[0].tpn_host : NULL;
7852+
}
7853+
78207854
/** Get the branch parameter. @NEW_1_12_7. */
78217855
char const *nta_outgoing_branch(nta_outgoing_t const *orq)
78227856
{
@@ -7923,6 +7957,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
79237957
int explicit_transport = 1;
79247958
int call_tls_orq_connect_timeout_is_set = 0;
79257959
int call_tls_orq_connect_timeout = 0;
7960+
void *intercept_query_results = 0;
79267961

79277962
tagi_t const *t;
79287963
tport_t *override_tport = NULL;
@@ -7969,6 +8004,8 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
79698004
stateless = t->t_value != 0;
79708005
else if (ntatag_delay_sending == tt)
79718006
delay_sending = t->t_value != 0;
8007+
else if (ntatag_intercept_query_results == tt)
8008+
intercept_query_results = (void *)t->t_value;
79728009
else if (ntatag_branch_key == tt)
79738010
branch = (void *)t->t_value;
79748011
else if (ntatag_pass_100 == tt)
@@ -8013,6 +8050,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
80138050
orq->orq_call_id = sip->sip_call_id;
80148051
orq->orq_tags = tl_afilter(home, tport_tags, ta_args(ta));
80158052
orq->orq_delayed = delay_sending != 0;
8053+
orq->orq_intercept_query_results = intercept_query_results;
80168054
orq->orq_pass_100 = pass_100 != 0;
80178055
orq->orq_sigcomp_zap = sigcomp_zap;
80188056
orq->orq_sigcomp_new = comp != NONE && comp != NULL;
@@ -11010,6 +11048,8 @@ void outgoing_answer_a(sres_context_t *orq, sres_query_t *q,
1101011048
outgoing_query_results(orq, sq, results, found);
1101111049
}
1101211050

11051+
int nua_client_intercept_query_results(const void *nua_handle, void *cr, nta_outgoing_t *orq, sip_t const *sip);
11052+
1101311053
/** Store A/AAAA query results */
1101411054
static void
1101511055
outgoing_query_results(nta_outgoing_t *orq,
@@ -11053,6 +11093,29 @@ outgoing_query_results(nta_outgoing_t *orq,
1105311093

1105411094
if (rlen > 0) {
1105511095
orq->orq_resolved = 1;
11096+
if (orq->orq_intercept_query_results && orq->orq_callback) {
11097+
nta_outgoing_query_results_data_t orq_query_results = { 0 };
11098+
11099+
SU_DEBUG_0(("intercepted query results\n" VA_NONE));
11100+
11101+
orq_query_results.results = results;
11102+
orq_query_results.found = rlen;
11103+
11104+
/* orq->orq_query_results field works as an argument to the orq_callback function */
11105+
orq->orq_query_results = &orq_query_results;
11106+
11107+
if (orq->orq_callback == outgoing_default_cb) {
11108+
int res = nua_client_intercept_query_results(orq->orq_intercept_query_results, NULL, orq, NULL);
11109+
/* No need to return here if res is 1 */
11110+
(void)res;
11111+
} else {
11112+
orq->orq_callback(orq->orq_magic, orq, NULL);
11113+
}
11114+
11115+
/* orq->orq_query_results field argument must be NULLed after the function call */
11116+
orq->orq_query_results = NULL;
11117+
}
11118+
1105611119
orq->orq_tpn->tpn_host = results[0];
1105711120
if (sq->sq_proto) orq->orq_tpn->tpn_proto = sq->sq_proto;
1105811121
if (sq->sq_port[0]) orq->orq_tpn->tpn_port = sq->sq_port;

libsofia-sip-ua/nta/nta_tag.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,6 +1974,7 @@ tag_typedef_t ntatag_s_tout_response = USIZETAG_TYPEDEF(s_tout_response);
19741974
/* Internal */
19751975
tag_typedef_t ntatag_delay_sending = BOOLTAG_TYPEDEF(delay_sending);
19761976
tag_typedef_t ntatag_incomplete = BOOLTAG_TYPEDEF(incomplete);
1977+
tag_typedef_t ntatag_intercept_query_results = PTRTAG_TYPEDEF(intercept_query_results);
19771978

19781979

19791980
tag_typedef_t ntatag_q_in_completed = SIZETAG_TYPEDEF(q_in_completed);

libsofia-sip-ua/nta/sofia-sip/nta.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ enum {
113113
/**< Maximum value for timers. */
114114
};
115115

116+
typedef struct nta_outgoing_query_results_data_s {
117+
char **results;
118+
size_t found;
119+
} nta_outgoing_query_results_data_t;
120+
116121
/* ----------------------------------------------------------------------
117122
* 3) Agent-level prototypes
118123
*/
@@ -404,6 +409,10 @@ SOFIAPUBFUN char const *nta_outgoing_branch(nta_outgoing_t const *orq);
404409

405410
SOFIAPUBFUN unsigned nta_outgoing_delay(nta_outgoing_t const *orq);
406411

412+
SOFIAPUBFUN char const *nta_outgoing_cannon(nta_outgoing_t const *orq);
413+
SOFIAPUBFUN char const *nta_outgoing_host(nta_outgoing_t const *orq);
414+
SOFIAPUBFUN nta_outgoing_query_results_data_t *nta_outgoing_query_results(nta_outgoing_t const *orq, char ***results, size_t *found);
415+
407416
SOFIAPUBFUN url_t const *nta_outgoing_request_uri(nta_outgoing_t const *orq);
408417
SOFIAPUBFUN url_t const *nta_outgoing_route_uri(nta_outgoing_t const *orq);
409418

libsofia-sip-ua/nta/sofia-sip/nta_tag.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ NTA_DLL extern tag_typedef_t ntatag_rseq;
417417
NTA_DLL extern tag_typedef_t ntatag_rseq_ref;
418418
#define NTATAG_RSEQ_REF(x) ntatag_rseq_ref, tag_uint_vr(&(x))
419419

420+
NTA_DLL extern tag_typedef_t ntatag_intercept_query_results;
421+
#define NTATAG_INTERCEPT_QUERY_RESULTS(x) ntatag_intercept_query_results, tag_ptr_v((x))
422+
423+
NTA_DLL extern tag_typedef_t ntatag_intercept_results_ref;
424+
#define NTATAG_INTERCEPT_QUERY_RESULTS_REF(x) ntatag_intercept_query_results_ref, tag_ptr_vr(&(x))
425+
420426
/* ====================================================================== */
421427
/* Tags for statistics. */
422428

libsofia-sip-ua/nua/nua_client.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ int nua_base_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip,
946946
url_string_t * proxy = NH_PGET(nh, proxy);
947947
int call_tls_orq_connect_timeout_is_set = NH_PISSET(nh, call_tls_orq_connect_timeout);
948948
uint32_t call_tls_orq_connect_timeout = NH_PGET(nh, call_tls_orq_connect_timeout);
949+
int intercept_query_results_is_set = NUA_PISSET(nh->nh_nua, nh, intercept_query_results);
949950

950951
if (nh->nh_auth) {
951952
if (cr->cr_challenged ||
@@ -964,6 +965,8 @@ int nua_base_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip,
964965
nua_client_request_ref(cr),
965966
NULL,
966967
msg,
968+
TAG_IF(intercept_query_results_is_set,
969+
NTATAG_INTERCEPT_QUERY_RESULTS(nh)),
967970
TAG_IF(proxy_is_set,
968971
NTATAG_DEFAULT_PROXY(proxy)),
969972
TAG_IF(call_tls_orq_connect_timeout_is_set,
@@ -978,6 +981,81 @@ int nua_base_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip,
978981
return 0;
979982
}
980983

984+
static inline void nua_client_intercept_response(nua_client_request_t *cr,
985+
int status,
986+
char const *phrase,
987+
sip_t const *sip)
988+
{
989+
nua_handle_t *nh = cr->cr_owner;
990+
nua_t *nua = nh ? nh->nh_nua : NULL;
991+
nua_dialog_usage_t *du = cr->cr_usage;
992+
unsigned intercept_query_results = nh ? NUA_PISSET(nh->nh_nua, nh, intercept_query_results) : 0;
993+
994+
if (intercept_query_results && sip && status != 408 && nua) {
995+
/* At this point we have a successful response */
996+
nua_dialog_state_t *ds = du ? du->du_dialog : NULL;
997+
998+
SU_DEBUG_0(("Normal response detected. Remembering IP...\n" VA_NONE));
999+
1000+
if (!ds) {
1001+
ds = nh->nh_ds;
1002+
}
1003+
1004+
/* Let's remember the IP */
1005+
if (ds && ds->ds_intercepted_ip == NULL) {
1006+
const char *host = nta_outgoing_host(cr->cr_orq);
1007+
1008+
if (host) {
1009+
SU_DEBUG_0(("host remembered: [%s]\n", host));
1010+
ds->ds_intercepted_ip = su_strdup(ds->ds_owner->nh_home, host);
1011+
}
1012+
}
1013+
}
1014+
}
1015+
1016+
int nua_client_intercept_query_results(const void *nua_handle, void *_cr,
1017+
nta_outgoing_t *orq,
1018+
sip_t const *sip)
1019+
{
1020+
nua_client_request_t *cr = (nua_client_request_t *)_cr;
1021+
char **results = NULL;
1022+
size_t found = 0;
1023+
1024+
if (nta_outgoing_query_results(orq, &results, &found) != NULL) {
1025+
/* See NTATAG_INTERCEPT_QUERY_RESULTS and NUTAG_INTERCEPT_QUERY_RESULTS */
1026+
nua_handle_t *nh = nua_handle ? (nua_handle_t *)nua_handle : cr->cr_owner;
1027+
nua_dialog_usage_t *du = cr ? cr->cr_usage : NULL;
1028+
nua_dialog_state_t *ds = du ? du->du_dialog : NULL;
1029+
1030+
SU_DEBUG_0(("Query results have been intercepted. Trying to override...\n" VA_NONE));
1031+
1032+
if (!ds && nh) {
1033+
ds = nh->nh_ds;
1034+
}
1035+
1036+
if (ds && ds->ds_intercepted_ip) {
1037+
if (found) {
1038+
msg_t *response = nta_outgoing_getresponse(orq);
1039+
su_home_t *home = response ? msg_home(response) : msg_home(nh);
1040+
1041+
SU_DEBUG_0(("Intercepted IP address: [%s]->[%s]\n", results[0], ds->ds_intercepted_ip));
1042+
results[0] = su_strdup(home, ds->ds_intercepted_ip);
1043+
msg_destroy(response);
1044+
1045+
if (found > 1) {
1046+
results[1] = NULL;
1047+
}
1048+
}
1049+
}
1050+
1051+
/* Function caller must return */
1052+
return 1;
1053+
}
1054+
1055+
/* No-op */
1056+
return 0;
1057+
}
1058+
9811059
/** Callback for nta client transaction */
9821060
int
9831061
nua_client_orq_response(nua_client_request_t *cr,
@@ -987,6 +1065,11 @@ nua_client_orq_response(nua_client_request_t *cr,
9871065
int status;
9881066
char const *phrase;
9891067

1068+
/* See NTATAG_INTERCEPT_QUERY_RESULTS and NUTAG_INTERCEPT_QUERY_RESULTS */
1069+
if (nua_client_intercept_query_results(NULL, cr, orq, sip)) {
1070+
return 0;
1071+
}
1072+
9901073
if (sip && sip->sip_status) {
9911074
status = sip->sip_status->st_status;
9921075
phrase = sip->sip_status->st_phrase;
@@ -1041,6 +1124,8 @@ int nua_client_response(nua_client_request_t *cr,
10411124
nua_dialog_usage_t *du = cr->cr_usage;
10421125
int retval = 0;
10431126

1127+
nua_client_intercept_response(cr, status,phrase, sip);
1128+
10441129
if (cr->cr_restarting)
10451130
return 0;
10461131

libsofia-sip-ua/nua/nua_dialog.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ int nua_dialog_zap(nua_owner_t *own,
215215
nta_leg_destroy(ds->ds_leg), ds->ds_leg = NULL;
216216
/* Remote tag */
217217
su_free(own, (void *)ds->ds_remote_tag), ds->ds_remote_tag = NULL;
218+
/* Intercepted IP */
219+
su_free(own, (void *)ds->ds_intercepted_ip), ds->ds_intercepted_ip = NULL;
218220
/* Ready to set route/remote target */
219221
ds->ds_route = 0;
220222

libsofia-sip-ua/nua/nua_dialog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct nua_dialog_state
8181
* Should be non-NULL
8282
* if dialog is established.
8383
*/
84+
char const *ds_intercepted_ip;
8485

8586
struct nua_dialog_peer_info {
8687
sip_via_t *nr_via;

libsofia-sip-ua/nua/nua_params.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
275275
* NUTAG_AUTOALERT() \n
276276
* NUTAG_AUTOANSWER() \n
277277
* NUTAG_CALL_TLS_ORQ_CONNECT_TIMEOUT() \n
278+
* NUTAG_INTERCEPT_QUERY_RESULTS() \n
278279
* NUTAG_CALLEE_CAPS() \n
279280
* NUTAG_DETECT_NETWORK_UPDATES() \n
280281
* NUTAG_EARLY_ANSWER() \n
@@ -400,6 +401,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
400401
* NUTAG_AUTOALERT() \n
401402
* NUTAG_AUTOANSWER() \n
402403
* NUTAG_CALL_TLS_ORQ_CONNECT_TIMEOUT() \n
404+
* NUTAG_INTERCEPT_QUERY_RESULTS() \n
403405
* NUTAG_CALLEE_CAPS() \n
404406
* NUTAG_EARLY_ANSWER() \n
405407
* NUTAG_EARLY_MEDIA() \n
@@ -712,6 +714,9 @@ static int nhp_set_tags(su_home_t *home,
712714
else if (tag == nutag_call_tls_orq_connect_timeout) {
713715
NHP_SET(nhp, call_tls_orq_connect_timeout, (uint32_t)value);
714716
}
717+
else if (tag == nutag_intercept_query_results) {
718+
NHP_SET(nhp, intercept_query_results, value != 0);
719+
}
715720
/* NUTAG_MAX_SUBSCRIPTIONS(max_subscriptions) */
716721
else if (tag == nutag_max_subscriptions) {
717722
NHP_SET(nhp, max_subscriptions, (unsigned)value);
@@ -1499,6 +1504,7 @@ int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags)
14991504
* NUTAG_AUTOALERT() \n
15001505
* NUTAG_AUTOANSWER() \n
15011506
* NUTAG_CALL_TLS_ORQ_CONNECT_TIMEOUT() \n
1507+
* NUTAG_INTERCEPT_QUERY_RESULTS() \n
15021508
* NUTAG_CALLEE_CAPS() \n
15031509
* NUTAG_DETECT_NETWORK_UPDATES() \n
15041510
* NUTAG_EARLY_ANSWER() \n
@@ -1674,6 +1680,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
16741680

16751681
TIF(NUTAG_RETRY_COUNT, retry_count),
16761682
TIF(NUTAG_CALL_TLS_ORQ_CONNECT_TIMEOUT, call_tls_orq_connect_timeout),
1683+
TIF(NUTAG_INTERCEPT_QUERY_RESULTS, intercept_query_results),
16771684
TIF(NUTAG_MAX_SUBSCRIPTIONS, max_subscriptions),
16781685

16791686
TIF(NUTAG_SOA_NAME, soa_name),

libsofia-sip-ua/nua/nua_params.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct nua_handle_preferences
6161
unsigned nhp_retry_count; /**< times to retry a request */
6262
unsigned nhp_max_subscriptions;
6363
uint32_t nhp_call_tls_orq_connect_timeout;
64+
unsigned nhp_intercept_query_results;
6465

6566
/* Session-related preferences */
6667
char const *nhp_soa_name;
@@ -221,6 +222,7 @@ struct nua_handle_preferences
221222
unsigned nhb_retry_after_enable:1;
222223
unsigned nhb_auto_invite_100:1;
223224
unsigned nhb_call_tls_orq_connect_timeout:1;
225+
unsigned nhb_intercept_query_results:1;
224226
unsigned :0;
225227
} set_bits;
226228
unsigned set_unsigned[2];

libsofia-sip-ua/nua/nua_session.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
12391239
sip_proxy_authorization_t *pa;
12401240
sip_cseq_t *cseq;
12411241
int proxy_is_set;
1242+
int intercept_query_results_is_set;
12421243
url_string_t *proxy;
12431244
nta_outgoing_t *ack;
12441245
int status = 200;
@@ -1359,10 +1360,13 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
13591360

13601361
proxy_is_set = NH_PISSET(nh, proxy);
13611362
proxy = NH_PGET(nh, proxy);
1363+
intercept_query_results_is_set = NUA_PISSET(nh->nh_nua, nh, intercept_query_results);
13621364

13631365
if ((ack = nta_outgoing_mcreate(nh->nh_nua->nua_nta, NULL, NULL, NULL,
13641366
msg,
13651367
NTATAG_ACK_BRANCH(invite_branch),
1368+
TAG_IF(intercept_query_results_is_set,
1369+
NTATAG_INTERCEPT_QUERY_RESULTS(nh)),
13661370
TAG_IF(proxy_is_set,
13671371
NTATAG_DEFAULT_PROXY(proxy)),
13681372
SIPTAG_END(),

0 commit comments

Comments
 (0)