Browse code

Merge 30a3c672c14421894dda4c11a47a71b5eceafab7 into 234b02236b3ad13cdaf5624d11c727ad7d804747

alexyosifov authored on 12/08/2020 14:39:18 • GitHub committed on 12/08/2020 14:39:18
Showing 11 changed files
... ...
@@ -76,6 +76,7 @@ extern usrloc_api_t ul;
76 76
 extern struct tm_binds tmb;
77 77
 
78 78
 #define IPSEC_SEND_FORCE_SOCKET		0x01 /* if set - set send force socket for request messages */
79
+#define IPSEC_REVERSE_SEARCH		0x02 /* if set - start searching from the last element */
79 80
 
80 81
 int bind_ipsec_pcscf(ipsec_pcscf_api_t* api) {
81 82
 	if(!api){
... ...
@@ -663,7 +664,7 @@ int ipsec_create(struct sip_msg* m, udomain_t* d)
663 664
 
664 665
     ul.lock_udomain(d, &ci.via_host, ci.via_port, ci.via_prot);
665 666
 
666
-    if (ul.get_pcontact(d, &ci, &pcontact) != 0) {
667
+    if (ul.get_pcontact(d, &ci, &pcontact, 0) != 0) {
667 668
         LM_ERR("Contact doesn't exist\n");
668 669
         goto cleanup;
669 670
     }
... ...
@@ -802,7 +803,7 @@ int ipsec_forward(struct sip_msg* m, udomain_t* d, int _cflags)
802 803
 
803 804
     ul.lock_udomain(d, &ci.via_host, ci.via_port, ci.via_prot);
804 805
 
805
-    if (ul.get_pcontact(d, &ci, &pcontact) != 0) {
806
+    if (ul.get_pcontact(d, &ci, &pcontact, _cflags & IPSEC_REVERSE_SEARCH) != 0) {
806 807
         LM_ERR("Contact doesn't exist\n");
807 808
         goto cleanup;
808 809
     }
... ...
@@ -946,7 +947,7 @@ int ipsec_destroy(struct sip_msg* m, udomain_t* d)
946 947
 
947 948
     ul.lock_udomain(d, &ci.via_host, ci.via_port, ci.via_prot);
948 949
 
949
-    if (ul.get_pcontact(d, &ci, &pcontact) != 0) {
950
+    if (ul.get_pcontact(d, &ci, &pcontact, 0) != 0) {
950 951
         LM_ERR("Contact doesn't exist\n");
951 952
         goto cleanup;
952 953
     }
... ...
@@ -243,8 +243,9 @@ ipsec_create("location");
243 243
           stores the contacts.
244 244
           </para>
245 245
           <para>
246
-          <emphasis>flags</emphasis> - Set send force socket for request messages.
247
-          If 1 - set force socket for request messages. Useful for ipsec and TCP.
246
+          <emphasis>flags</emphasis> - bitwise flag:
247
+          0x01 - set force socket for request messages. Useful for ipsec and TCP.
248
+          0x02 - reverse search for a contact in the memory. Useful when contact alias is disabled.
248 249
           This is an optional parameter, default value - 0.
249 250
           </para>
250 251
         </listitem>
... ...
@@ -275,7 +275,7 @@ void cdp_cb_event_process()
275 275
 												contact_info.aor = p_session_data->registration_aor;
276 276
 												contact_info.reg_state = PCONTACT_ANY;
277 277
 
278
-												if (ul.get_pcontact(domain, &contact_info, &pcontact) != 0) {
278
+												if (ul.get_pcontact(domain, &contact_info, &pcontact, 0) != 0) {
279 279
 														LM_DBG("no contact found for terminated Rx reg session..... ignoring\n");
280 280
 												} else {
281 281
 														LM_DBG("Updating contact [%.*s] after Rx reg session terminated, setting state to PCONTACT_DEREG_PENDING_PUBLISH\n", pcontact->aor.len, pcontact->aor.s);
... ...
@@ -1314,7 +1314,7 @@ static int w_rx_aar_register(struct sip_msg *msg, char* route, char* str1, char*
1314 1314
 								contact_info.received_host.len = 0;
1315 1315
 								contact_info.reg_state = PCONTACT_ANY; //search for any state
1316 1316
 
1317
-								if (ul.get_pcontact(domain_t, &contact_info, &pcontact) != 0) {
1317
+								if (ul.get_pcontact(domain_t, &contact_info, &pcontact, 0) != 0) {
1318 1318
 										LM_ERR("This contact does not exist in PCSCF usrloc - error in cfg file\n");
1319 1319
 										ul.unlock_udomain(domain_t, &vb->host, vb->port, vb->proto);
1320 1320
 										lock_release(saved_t_data->lock);
... ...
@@ -321,7 +321,7 @@ void async_aar_reg_callback(int is_timeout, void *param, AAAMessage *aaa, long e
321 321
         contact_info.via_prot = local_data->via_proto;
322 322
         contact_info.reg_state = PCONTACT_ANY;
323 323
 
324
-        if (ul.get_pcontact(domain_t, &contact_info, &pcontact) != 0) {
324
+        if (ul.get_pcontact(domain_t, &contact_info, &pcontact, 0) != 0) {
325 325
             LM_ERR("Shouldn't get here, can't find contact....\n");
326 326
             ul.unlock_udomain(domain_t, &local_data->via_host, local_data->via_port, local_data->via_proto);
327 327
             goto error;
... ...
@@ -182,7 +182,7 @@ int process_contact(udomain_t * _d, int expires, str contact_uri, int contact_st
182 182
         LM_DBG("Contact in NOTIFY does not have an alias....\n");
183 183
     }
184 184
 
185
-    if (ul.get_pcontact(_d, &ci, &pcontact) != 0) { //contact does not exist
185
+    if (ul.get_pcontact(_d, &ci, &pcontact, 0) != 0) { //contact does not exist
186 186
         if (contact_state == STATE_TERMINATED) {
187 187
             LM_DBG("This contact: <%.*s> is in state terminated and is not in usrloc, ignore\n", contact_uri.len, contact_uri.s);
188 188
             ret = RESULT_CONTACTS_FOUND;
... ...
@@ -128,6 +128,7 @@ static inline int update_contacts(struct sip_msg *req,struct sip_msg *rpl, udoma
128 128
 	char *alias_start, *p, *port_s, *proto_s;
129 129
 	char portbuf[5];
130 130
 	str alias_s;
131
+	char srcip[50];
131 132
 
132 133
 	pcscf_act_time();
133 134
 	local_time_now = time_now;
... ...
@@ -196,10 +197,18 @@ static inline int update_contacts(struct sip_msg *req,struct sip_msg *rpl, udoma
196 197
 							ci.searchflag = SEARCH_RECEIVED;
197 198
 						}
198 199
 					}
199
-				} 
200
+				} else {
201
+					ci.received_host.len = ip_addr2sbuf(&req->rcv.src_ip, srcip, sizeof(srcip));
202
+					ci.received_host.s = srcip;
203
+					ci.received_port = req->rcv.src_port;
204
+					ci.received_proto = req->rcv.proto;
205
+					ci.searchflag = SEARCH_RECEIVED;
206
+					LM_DBG("received from request: host [%.*s], port [%d] , proto [%d]\n", 
207
+							ci.received_host.len, ci.received_host.s, ci.received_port, ci.received_proto);
208
+				}
200 209
 				
201 210
 				ul.lock_udomain(_d, &puri.host, port, puri.proto);
202
-				if (ul.get_pcontact(_d, &ci, &pcontact) != 0) { //need to insert new contact
211
+				if (ul.get_pcontact(_d, &ci, &pcontact, 0) != 0) { //need to insert new contact
203 212
 					if ((expires-local_time_now)<=0) { //remove contact - de-register
204 213
 						LM_DBG("This is a de-registration for contact <%.*s> but contact is not in usrloc - ignore\n", c->uri.len, c->uri.s);
205 214
 						goto next_contact;
... ...
@@ -362,7 +371,7 @@ int save_pending(struct sip_msg* _m, udomain_t* _d) {
362 371
 	}
363 372
 
364 373
 	ul.lock_udomain(_d, &ci.via_host, ci.via_port, ci.via_prot);
365
-	if (ul.get_pcontact(_d, &ci, &pcontact) != 0) { //need to insert new contact
374
+	if (ul.get_pcontact(_d, &ci, &pcontact, 0) != 0) { //need to insert new contact
366 375
 		ipsec_pcscf.ipsec_reconfig(); // try to clean all ipsec SAs/Policies if there is no registered contacts
367 376
 
368 377
 		LM_DBG("Adding pending pcontact: <%.*s>\n", c->uri.len, c->uri.s);
... ...
@@ -261,7 +261,7 @@ tryagain:
261 261
 	if (b && b->contacts) {
262 262
 		for (ct = b->contacts; ct; ct = ct->next) {
263 263
 			search_ci.aor = ct->uri;
264
-			if (ul.get_pcontact(_d, &search_ci, &c) == 0) {
264
+			if (ul.get_pcontact(_d, &search_ci, &c, 0) == 0) {
265 265
 				if (checkcontact(_m, c) != 0) {
266 266
 					c = NULL;
267 267
 				} else {
... ...
@@ -278,7 +278,7 @@ tryagain:
278 278
 		//			received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
279 279
 		//			received_host.s = srcip;
280 280
 		search_ci.searchflag = SEARCH_RECEIVED;
281
-		if (ul.get_pcontact(_d, &search_ci, &c) == 1) {
281
+		if (ul.get_pcontact(_d, &search_ci, &c, 0) == 1) {
282 282
 			LM_DBG("No entry in usrloc for %.*s:%i (Proto %i) found!\n", received_host.len, received_host.s, _m->rcv.src_port, _m->rcv.proto);
283 283
 		} else {
284 284
 			if (checkcontact(_m, c) != 0) {
... ...
@@ -290,7 +290,7 @@ tryagain:
290 290
 	if ((c == NULL) && (is_registered_fallback2ip == 2)) {
291 291
 		LM_INFO("Contact not found based on IP/Port/Proto, trying Contact-header\n");
292 292
 		search_ci.searchflag = SEARCH_NORMAL;
293
-		if (ul.get_pcontact(_d, &search_ci, &c) == 1) {
293
+		if (ul.get_pcontact(_d, &search_ci, &c, 0) == 1) {
294 294
 		} else {
295 295
 			if (checkcontact(_m, c) != 0) {
296 296
 				c = NULL;
... ...
@@ -785,7 +785,7 @@ int pcscf_unregister(udomain_t* _d, str * uri, str * received_host, int received
785 785
         search_ci.aor.len = uri->len;
786 786
 		search_ci.reg_state = PCONTACT_ANY;
787 787
 
788
-	if (ul.get_pcontact(_d, &search_ci, &pcontact) == 0) {
788
+	if (ul.get_pcontact(_d, &search_ci, &pcontact, 0) == 0) {
789 789
 		/* Lock this record while working with the data: */
790 790
 		ul.lock_udomain(_d, &pcontact->via_host, pcontact->via_port, pcontact->via_proto);
791 791
 
... ...
@@ -444,9 +444,10 @@ error:
444 444
  * @udomain_t* _d - domain to search in
445 445
  * @str* _contact - contact to search for - should be a SIP URI
446 446
  * @struct pontact** _c - contact to return to if found (null if not found)
447
+ * @int reverse_search - reverse search for a contact in the memory
447 448
  * @return 0 if found <>0 if not
448 449
  */
449
-int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact** _c) {
450
+int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact** _c, int reverse_search) {
450 451
 	unsigned int sl, i, j, aorhash, params_len, has_rinstance=0;
451 452
 	struct pcontact* c;
452 453
 	struct sip_uri needle_uri;
... ...
@@ -454,9 +455,10 @@ int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact**
454 455
 	char *params, *sep;
455 456
 	str rinstance = {0, 0};
456 457
         
457
-	LM_DBG("Searching for contact with AOR [%.*s] in P-CSCF usrloc based on VIA [%d://%.*s:%d] Received [%d://%.*s:%d], Search flag is %d\n",
458
+	LM_DBG("Searching for contact with AOR [%.*s] in P-CSCF usrloc based on VIA [%d://%.*s:%d] Received [%d://%.*s:%d], Search flag is %d, reverse_search %d\n",
458 459
 		contact_info->aor.len, contact_info->aor.s, contact_info->via_prot, contact_info->via_host.len, contact_info->via_host.s, contact_info->via_port,
459
-		contact_info->received_proto, contact_info->received_host.len, contact_info->received_host.s, contact_info->received_port, contact_info->searchflag);
460
+		contact_info->received_proto, contact_info->received_host.len, contact_info->received_host.s, contact_info->received_port, contact_info->searchflag,
461
+		reverse_search);
460 462
 
461 463
 	/* parse the uri in the NOTIFY */
462 464
 	if (contact_info->aor.len>0 && contact_info->aor.s){
... ...
@@ -501,7 +503,7 @@ int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact**
501 503
 	sl = aorhash & (_d->size - 1);
502 504
         
503 505
 	LM_DBG("get_pcontact slot is [%d]\n", sl);
504
-	c = _d->table[sl].first;
506
+	c = reverse_search ? _d->table[sl].last : _d->table[sl].first;
505 507
 
506 508
 	for (i = 0; i < _d->table[sl].n; i++) {
507 509
 		LM_DBG("comparing contact with aorhash [%u], aor [%.*s]\n", c->aorhash, c->aor.len, c->aor.s);
... ...
@@ -563,7 +565,7 @@ int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact**
563 565
 							c->rinstance.len, c->rinstance.s);
564 566
 					if ((rinstance.len == c->rinstance.len) && memcmp(rinstance.s, c->rinstance.s, rinstance.len) != 0) {
565 567
 						LM_DBG("rinstance does not match - no match here...\n");
566
-						c = c->next;
568
+						c = reverse_search ? c->prev : c->next;
567 569
 						continue;
568 570
 					}
569 571
 				}
... ...
@@ -571,7 +573,7 @@ int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact**
571 573
 				if ((contact_info->extra_search_criteria & SEARCH_SERVICE_ROUTES) && contact_info->num_service_routes > 0) {
572 574
 					LM_DBG("have %d service routes to search for\n", contact_info->num_service_routes);
573 575
 					if (contact_info->num_service_routes != c->num_service_routes) {
574
-						c = c->next;
576
+						c = reverse_search ? c->prev : c->next;
575 577
 						LM_DBG("number of service routes do not match - failing\n");
576 578
 						continue;
577 579
 					} 
... ...
@@ -588,7 +590,7 @@ int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact**
588 590
 						}
589 591
 					}
590 592
 					if (serviceroutematch == 0) {
591
-						c = c->next;
593
+						c = reverse_search ? c->prev : c->next;
592 594
 						continue;
593 595
 					}
594 596
 				}
... ...
@@ -596,14 +598,14 @@ int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact**
596 598
 				//finally check state being searched for
597 599
 				if ( (contact_info->reg_state != PCONTACT_ANY) && ((contact_info->reg_state & c->reg_state) == 0)) {
598 600
 					LM_DBG("can't find contact for requested reg state [%d] - (have [%d])\n", contact_info->reg_state, c->reg_state);
599
-					c = c->next;
601
+					c = reverse_search ? c->prev : c->next;
600 602
 					continue;
601 603
 				}
602 604
 				*_c = c;
603 605
 				return 0;
604 606
 			}
605 607
 		}
606
-		c = c->next;
608
+		c = reverse_search ? c->prev : c->next;
607 609
 	}
608 610
         
609 611
 	LM_DBG("contact not found in memory\n");
... ...
@@ -74,7 +74,7 @@ void unlock_ulslot(udomain_t* _d, int i);
74 74
 int update_rx_regsession(struct udomain* _d, str* session_id, struct pcontact* _c);
75 75
 int update_pcontact(struct udomain* _d, struct pcontact_info* _ci, struct pcontact* _c);
76 76
 int insert_pcontact(struct udomain* _d, str* _contact, struct pcontact_info* _ci, struct pcontact** _r);
77
-int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact** _r);
77
+int get_pcontact(udomain_t* _d, pcontact_info_t* contact_info, struct pcontact** _c, int reverse_search);
78 78
 int assert_identity(udomain_t* _d, str * _host, unsigned short _port, unsigned short _proto, str * _identity);
79 79
 int delete_pcontact(udomain_t* _d, struct pcontact* _r);
80 80
 int unreg_pending_contacts_cb(udomain_t* _d, pcontact_t* _c, int type);
... ...
@@ -237,7 +237,7 @@ typedef struct pcontact {
237 237
     struct pcontact* next; /*!< Previous item in the hash entry */
238 238
 } pcontact_t;
239 239
 
240
-typedef int (*get_pcontact_t)(struct udomain* _d, pcontact_info_t* contact_info, struct pcontact** _c);
240
+typedef int (*get_pcontact_t)(struct udomain* _d, pcontact_info_t* contact_info, struct pcontact** _c, int reverse_search);
241 241
 
242 242
 typedef int (*assert_identity_t)(struct udomain* _d, str * _host, unsigned short _port, unsigned short _proto, str * _identity);
243 243