Browse code

Merge pull request #3 from kamailio/master

Update my kamailio repository master after merging lrkproxy

mojtabaesfandiari authored on 10/03/2021 09:31:38 • GitHub committed on 10/03/2021 09:31:38
Showing 34 changed files
... ...
@@ -23,7 +23,7 @@ mod_list_extra=avp auth_diameter call_control call_obj dmq domainpolicy msrp \
23 23
 			carrierroute pdb qos sca seas sms sst timer tmrec uac_redirect \
24 24
 			xhttp xhttp_rpc xprint jsonrpcs nosip dmq_usrloc statsd rtjson \
25 25
 			log_custom keepalive ss7ops app_sqlang acc_diameter evrexec \
26
-			sipjson xhttp_prom
26
+			sipjson lrkproxy xhttp_prom
27 27
 
28 28
 # - common modules depending on database
29 29
 mod_list_db=acc alias_db auth_db avpops cfg_db db_text db_flatstore \
... ...
@@ -495,7 +495,7 @@ again:
495 495
 		DBG("handle_stream read: eof on %s\n", s_c->parent->name);
496 496
 		goto close_connection;
497 497
 	}
498
-	LM_INFO("bytes read: %d\n", bytes_read);
498
+	LM_DBG("bytes read: %d\n", bytes_read);
499 499
 	r->end+=bytes_read;
500 500
 	if (bytes_read && (bytes_read<r->bytes_to_go)){
501 501
 		r->bytes_to_go-=bytes_read;
... ...
@@ -515,7 +515,7 @@ again:
515 515
 			/* error while processing the packet => close the connection */
516 516
 			goto close_connection;
517 517
 		}
518
-		LM_INFO("bytes processed: %d\n", bytes_processed);
518
+		LM_DBG("bytes processed: %d\n", bytes_processed);
519 519
 		r->proc+=bytes_processed;
520 520
 		r->bytes_to_go=bytes_needed;
521 521
 		if (bytes_needed>0){
... ...
@@ -484,7 +484,7 @@ static int ht_rm_items(sip_msg_t* msg, str* hname, str* op, str *val,
484 484
 		case 2:
485 485
 			if(strncmp(op->s, "re", 2)==0) {
486 486
 				isval.s = *val;
487
-				if (ht_dmq_replicate_action(HT_DMQ_RM_CELL_RE, &ht->name, NULL,
487
+				if ((ht->dmqreplicate > 0) && ht_dmq_replicate_action(HT_DMQ_RM_CELL_RE, &ht->name, NULL,
488 488
 							AVP_VAL_STR, &isval, mkey)!=0) {
489 489
 					LM_ERR("dmq relication failed (op %d)\n", mkey);
490 490
 				}
... ...
@@ -494,7 +494,7 @@ static int ht_rm_items(sip_msg_t* msg, str* hname, str* op, str *val,
494 494
 				return 1;
495 495
 			} else if(strncmp(op->s, "sw", 2)==0) {
496 496
 				isval.s = *val;
497
-				if (ht_dmq_replicate_action(HT_DMQ_RM_CELL_SW, &ht->name, NULL,
497
+				if ((ht->dmqreplicate > 0) &&ht_dmq_replicate_action(HT_DMQ_RM_CELL_SW, &ht->name, NULL,
498 498
 							AVP_VAL_STR, &isval, mkey)!=0) {
499 499
 					LM_ERR("dmq relication failed (op %d)\n", mkey);
500 500
 				}
... ...
@@ -280,6 +280,10 @@ int diameter_request(struct sip_msg * msg, char* peer, char* appid, char* comman
280 280
 		}
281 281
 		LM_DBG("Peer %.*s\n", s_peer.len, s_peer.s);
282 282
 	}
283
+	if (get_str_fparam(&s_message, msg, (fparam_t*)message) < 0) {
284
+		LM_ERR("failed to get Message\n");
285
+		return -1;
286
+	}
283 287
 	if (get_str_fparam(&s_appid, msg, (fparam_t*)appid) < 0) {
284 288
 		LM_ERR("failed to get App-ID\n");
285 289
 		return -1;
... ...
@@ -306,9 +310,14 @@ int diameter_request(struct sip_msg * msg, char* peer, char* appid, char* comman
306 310
 	session = cdpb.AAACreateSession(0);
307 311
 
308 312
 	req = cdpb.AAACreateRequest(i_appid, i_commandcode, Flag_Proxyable, session);
313
+        if (session) {
314
+	        cdpb.AAADropSession(session);
315
+                session = 0;
316
+        }
317
+
309 318
 	if (!req) goto error1;
310 319
 
311
-	if (addAVPsfromJSON(req, &s_message)) {
320
+	if (!addAVPsfromJSON(req, &s_message)) {
312 321
 		LM_ERR("Failed to parse JSON Request\n");
313 322
 		return -1;
314 323
 	}
... ...
@@ -322,7 +331,7 @@ int diameter_request(struct sip_msg * msg, char* peer, char* appid, char* comman
322 331
 		} else {
323 332
 			resp = cdpb.AAASendRecvMessageToPeer(req, &s_peer);
324 333
 			LM_DBG("Successfully sent diameter\n");
325
-			if (AAAmsg2json(resp, &responsejson) == 1) {
334
+			if (resp && AAAmsg2json(resp, &responsejson) == 1) {
326 335
 				return 1;
327 336
 			} else {
328 337
 				LM_ERR("Failed to convert response to JSON\n");
... ...
@@ -337,7 +346,7 @@ int diameter_request(struct sip_msg * msg, char* peer, char* appid, char* comman
337 346
 		} else {
338 347
 			resp = cdpb.AAASendRecvMessage(req);
339 348
 			LM_DBG("Successfully sent diameter\n");
340
-			if (AAAmsg2json(resp, &responsejson) == 1) {
349
+			if (resp && AAAmsg2json(resp, &responsejson) == 1) {
341 350
 				return 1;
342 351
 			} else {
343 352
 				LM_ERR("Failed to convert response to JSON\n");
344 353
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+#
2
+# lrkproxy module makefile
3
+#
4
+#
5
+# WARNING: do not run this directly, it should be run by the main Makefile
6
+
7
+include ../../Makefile.defs
8
+auto_gen=
9
+NAME=lrkproxy.so
10
+LIBS=
11
+
12
+SERLIBPATH=../../lib
13
+include ../../Makefile.modules
14
+
0 15
new file mode 100644
... ...
@@ -0,0 +1,316 @@
1
+lrkproxy Module
2
+
3
+Mojtaba Esfandiari.S
4
+
5
+   Nasim Telecom
6
+
7
+   Copyright � 2020 Nasim Telecom Inc.
8
+     __________________________________________________________________
9
+
10
+   Table of Contents
11
+
12
+   1. Admin Guide
13
+
14
+        1. Overview
15
+        2. LRKProxy Architecture
16
+
17
+              2.1. LRKP_Controlling Layer (LRKP_CL)
18
+              2.2. LRKP_Transport Stateful Layer (LRKP_TSL)
19
+
20
+        3. Multiple LRKProxy usage
21
+        4. Dependencies
22
+
23
+              4.1. Kamailio Modules
24
+              4.2. External Libraries or Applications
25
+              4.3. Parameters
26
+
27
+                    4.3.1. lrkproxy_sock (string)
28
+                    4.3.2. lrkproxy_disable_tout (integer)
29
+                    4.3.3. lrkproxy_tout (integer)
30
+                    4.3.4. lrkproxy_retr (integer)
31
+                    4.3.5. lrkp_alg (integer)
32
+                    4.3.6. hash_table_tout (integer)
33
+                    4.3.7. hash_table_size (integer)
34
+
35
+              4.4. Functions
36
+
37
+                    4.4.1. set_lrkproxy_set(setid)
38
+                    4.4.2. lrkproxy_manage([flags [, ip_address]])
39
+
40
+   List of Examples
41
+
42
+   1.1. Set lrkproxy_sock parameter
43
+   1.2. Set lrkproxy_disable_tout parameter
44
+   1.3. Set lrkproxy_tout parameter
45
+   1.4. Set lrkproxy_retr parameter
46
+   1.5. Set lrkp_alg parameter
47
+   1.6. Set hash_table_tout parameter
48
+   1.7. Set hash_table_size parameter
49
+   1.8. set_lrkproxy_set usage
50
+   1.9. lrkproxy_manage usage
51
+
52
+Chapter 1. Admin Guide
53
+
54
+   Table of Contents
55
+
56
+   1. Overview
57
+   2. LRKProxy Architecture
58
+
59
+        2.1. LRKP_Controlling Layer (LRKP_CL)
60
+        2.2. LRKP_Transport Stateful Layer (LRKP_TSL)
61
+
62
+   3. Multiple LRKProxy usage
63
+   4. Dependencies
64
+
65
+        4.1. Kamailio Modules
66
+        4.2. External Libraries or Applications
67
+        4.3. Parameters
68
+
69
+              4.3.1. lrkproxy_sock (string)
70
+              4.3.2. lrkproxy_disable_tout (integer)
71
+              4.3.3. lrkproxy_tout (integer)
72
+              4.3.4. lrkproxy_retr (integer)
73
+              4.3.5. lrkp_alg (integer)
74
+              4.3.6. hash_table_tout (integer)
75
+              4.3.7. hash_table_size (integer)
76
+
77
+        4.4. Functions
78
+
79
+              4.4.1. set_lrkproxy_set(setid)
80
+              4.4.2. lrkproxy_manage([flags [, ip_address]])
81
+
82
+1. Overview
83
+
84
+   This is a module that enables media streams to be relayed via an
85
+   lrkproxy. This module works with py_lrkproxy engine in:
86
+   https://github.com/mojtabaesfandiari/pylrkproxy This module does
87
+   relaying audio streams between peers in PREROUTING netfilter-hooking
88
+   section in kernel-space linux. The LRKProxy architecture is composed of
89
+   two different layers. These layers are independent of each other.
90
+
91
+2. LRKProxy Architecture
92
+
93
+   2.1. LRKP_Controlling Layer (LRKP_CL)
94
+   2.2. LRKP_Transport Stateful Layer (LRKP_TSL)
95
+
96
+2.1. LRKP_Controlling Layer (LRKP_CL)
97
+
98
+   The first layer is developed as User-Space application that allows
99
+   User-Space to directly access and manipulate cache data buffer and
100
+   packet buffer in Kernel-Space. This layer gets all information about
101
+   creating new sessions, active sessions and tear-down sessions which is
102
+   gotten from SDP body during signaling plan and relay them to the
103
+   LRKP-Transport Stateful Layer (LRKP- TSL).
104
+
105
+2.2. LRKP_Transport Stateful Layer (LRKP_TSL)
106
+
107
+   The second layer is developed in Kernel-Space as a main decision point
108
+   for RTP admission controller and Quickpath selector to where a received
109
+   packet should be forwarded with power of packet mangling framework in
110
+   the network stack.
111
+
112
+   The LRKP_CL and LRKP-TSL could be run as independence functions on
113
+   different machines. We could have one LRKP_CL with multiple LRKP-TSL on
114
+   different machines. The LRKP_CL could works with all LRKP-TSL with
115
+   different strategies(lrkp_alg parameter).
116
+
117
+3. Multiple LRKProxy usage
118
+
119
+   The LRKP_CL Layer can support multiple LRKP_TSL Layer for
120
+   balancing/distribution and control/selection purposes.
121
+
122
+   The module allows definition of several sets of LRKP_TSL.
123
+   Load-balancing will be performed over predefine algorithm by setting
124
+   lrkp_alg parameter.
125
+
126
+   IMPORTANT: This module does not support balancing inside a set like as
127
+   is done RTPProxy module based on the weight of each rtpproxy from the
128
+   set. The balancing would be run on different machine
129
+
130
+4. Dependencies
131
+
132
+   4.1. Kamailio Modules
133
+   4.2. External Libraries or Applications
134
+   4.3. Parameters
135
+
136
+        4.3.1. lrkproxy_sock (string)
137
+        4.3.2. lrkproxy_disable_tout (integer)
138
+        4.3.3. lrkproxy_tout (integer)
139
+        4.3.4. lrkproxy_retr (integer)
140
+        4.3.5. lrkp_alg (integer)
141
+        4.3.6. hash_table_tout (integer)
142
+        4.3.7. hash_table_size (integer)
143
+
144
+   4.4. Functions
145
+
146
+        4.4.1. set_lrkproxy_set(setid)
147
+        4.4.2. lrkproxy_manage([flags [, ip_address]])
148
+
149
+4.1. Kamailio Modules
150
+
151
+   The following modules must be loaded before this module:
152
+     * tm module - (optional) if you want to have lrkproxy_manage() fully
153
+       functional
154
+
155
+4.2. External Libraries or Applications
156
+
157
+   The following libraries or applications must be installed before
158
+   running Kamailio with this module loaded:
159
+     * None.
160
+
161
+4.3. Parameters
162
+
163
+4.3.1. lrkproxy_sock (string)
164
+
165
+   Used to define the list of LRKP_TSL instances to connect to. These can
166
+   be UNIX sockets or IPv4/IPv6 UDP sockets. Each modparam entry will
167
+   insert sockets into a single set with default value set ID '0'. To
168
+   define multiple LRKP_TSL, just add the instances in each modparam.
169
+
170
+   Default value is "NONE" (disabled).
171
+
172
+   Example 1.1. Set lrkproxy_sock parameter
173
+...
174
+# single lrkproxy
175
+modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.108:8080")
176
+
177
+# multiple lrkproxies for LB in diffenrent machine
178
+modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.108:8080")
179
+modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.109:8080")
180
+
181
+...
182
+
183
+4.3.2. lrkproxy_disable_tout (integer)
184
+
185
+   Once LRKP_TSL was found unreachable and marked as disabled, the LRKP_CL
186
+   module will not attempt to establish communication to LRKP_TSL for
187
+   lrkproxy_disable_tout seconds.
188
+
189
+   Default value is "60".
190
+
191
+   Example 1.2. Set lrkproxy_disable_tout parameter
192
+...
193
+modparam("lrkproxy", "lrkproxy_disable_tout", 20)
194
+...
195
+
196
+4.3.3. lrkproxy_tout (integer)
197
+
198
+   Timeout value in waiting for reply from LRKP_TSL.
199
+
200
+   Default value is "1".
201
+
202
+   Example 1.3. Set lrkproxy_tout parameter
203
+...
204
+modparam("lrkproxy", "lrkproxy_tout", 2)
205
+...
206
+
207
+4.3.4. lrkproxy_retr (integer)
208
+
209
+   How many times the LRKP_CL should retry to send and receive after
210
+   timeout was generated.
211
+
212
+   Default value is "5".
213
+
214
+   Example 1.4. Set lrkproxy_retr parameter
215
+...
216
+modparam("lrkproxy", "lrkproxy_retr", 2)
217
+...
218
+
219
+4.3.5. lrkp_alg (integer)
220
+
221
+   This parameter set the algorithm of LRKP_TSL selection. lrk_LINER=0,
222
+   lrk_RR=1
223
+
224
+   Default value is "0".
225
+
226
+   Example 1.5. Set lrkp_alg parameter
227
+...
228
+modparam("lrkproxy", "lrkp_alg", 1)
229
+...
230
+
231
+4.3.6. hash_table_tout (integer)
232
+
233
+   Number of seconds after an lrkproxy hash table entry is marked for
234
+   deletion. By default, this parameter is set to 3600 (seconds).
235
+
236
+   To maintain information about a selected rtp machine node, for a given
237
+   call, entries are added in a hashtable of (callid, viabranch) pairs.
238
+   When command comes, lookup callid, viabranch pairs. If found, return
239
+   chosen node. If not found, choose a new node, insert it in the hastable
240
+   and return the chosen node.
241
+
242
+   NOTE: In the current implementation, the actual deletion happens on the
243
+   fly, while insert/remove/lookup the hastable, only for the entries in
244
+   the insert/remove/lookup path.
245
+
246
+   NOTE: When configuring this parameter, one should consider maximum call
247
+   time VS share memory for unfinished calls.
248
+
249
+   Default value is "3600".
250
+
251
+   Example 1.6. Set hash_table_tout parameter
252
+...
253
+modparam("lrkproxy", "hash_table_tout", "3600")
254
+...
255
+
256
+4.3.7. hash_table_size (integer)
257
+
258
+   Size of the hash table. Default value is 128.
259
+
260
+   Default value is "128".
261
+
262
+   Example 1.7. Set hash_table_size parameter
263
+...
264
+modparam("lrkproxy", "hash_table_size", 256)
265
+...
266
+
267
+4.4. Functions
268
+
269
+4.4.1. set_lrkproxy_set(setid)
270
+
271
+   Sets the Id of the lrkproxy set to be used for the next
272
+   lrkproxy_manage() command. The parameter can be an integer or a config
273
+   variable holding an integer.
274
+
275
+   This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
276
+   BRANCH_ROUTE.
277
+
278
+   Example 1.8. set_lrkproxy_set usage
279
+...
280
+set_lrkproxy_set("0");
281
+lrkproxy_manage();
282
+...
283
+
284
+4.4.2. lrkproxy_manage([flags [, ip_address]])
285
+
286
+   Manage the LRKProxy session - it combines the functionality of
287
+   lrkproxy_offer(), lrkproxy_answer() and unforce_lrkproxy(), detecting
288
+   internally based on message type and method which one to execute.
289
+
290
+   IMPORTANT:The LRKProxy just has one function relating rtp packets. It
291
+   does not support combination of functionality of lrkproxy_offer(),
292
+   lrkproxy_answer() and unforce_lrkproxy() and other etc. So you have to
293
+   just use lrkproxy_manage.
294
+
295
+   Meaning of the parameters is as follows:
296
+     * flags - flags to turn on some features.
297
+          + internal,external - The shorthand of this flag is "ie". This
298
+            can be used to relay media sessions between two different NIC
299
+            from internal to external path.
300
+          + external,internal - The shorthand of this flag is "ei". This
301
+            can be used to relay media sessions between two different NIC
302
+            from external to internal path.
303
+     * ip_address - new SDP IP address.This optional parameter is under
304
+       development.
305
+
306
+   This function can be used from ANY_ROUTE.
307
+
308
+   Example 1.9. lrkproxy_manage usage
309
+...
310
+lrkproxy_manage();
311
+//or
312
+lrkproxy_manage("ie");
313
+//or
314
+lrkproxy_manage("ei");
315
+
316
+...
0 317
new file mode 100644
... ...
@@ -0,0 +1,4 @@
1
+docs = lrkproxy.xml
2
+
3
+docbook_dir = ../../../../doc/docbook
4
+include $(docbook_dir)/Makefile.module
0 5
new file mode 100644
... ...
@@ -0,0 +1,33 @@
1
+<?xml version="1.0" encoding='ISO-8859-1'?>
2
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4
+
5
+<!-- Include general documentation entities -->
6
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
7
+%docentities;
8
+
9
+]>
10
+
11
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
12
+	<bookinfo>
13
+	<title>lrkproxy Module</title>
14
+	<productname class="trade">&kamailioname;</productname>
15
+	<authorgroup>
16
+		<author>
17
+		<firstname>Mojtaba</firstname>
18
+		<surname>Esfandiari.S</surname>
19
+		<affiliation><orgname>Nasim Telecom</orgname></affiliation>
20
+		<address>
21
+			<email>esfandiari@nasimtelecom.com</email>
22
+		</address>
23
+		</author>
24
+	</authorgroup>
25
+	<copyright>
26
+		<year>2020</year>
27
+		<holder><ulink url='https://www.nasimtelecom.com/en/'>Nasim Telecom Inc.</ulink></holder>
28
+	</copyright>
29
+	</bookinfo>
30
+	<toc></toc>
31
+	
32
+	<xi:include href="lrkproxy_admin.xml"/>
33
+</book>
0 34
new file mode 100644
... ...
@@ -0,0 +1,364 @@
1
+<?xml version="1.0" encoding='ISO-8859-1'?>
2
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4
+
5
+<!-- Include general documentation entities -->
6
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
7
+%docentities;
8
+
9
+]>
10
+
11
+<!-- Module User's Guide -->
12
+
13
+<chapter>
14
+
15
+	<title>&adminguide;</title>
16
+
17
+	<section>
18
+	<title>Overview</title>
19
+	<para>
20
+		This is a module that enables media streams to be relayed via an
21
+ 		lrkproxy. This module works with py_lrkproxy engine in:
22
+		https://github.com/mojtabaesfandiari/pylrkproxy
23
+		This module does relaying audio streams between peers in
24
+		PREROUTING netfilter-hooking section in kernel-space linux.
25
+		The LRKProxy architecture is composed of two
26
+		different layers. These layers are independent of each
27
+		other.
28
+	</para>
29
+	</section>
30
+
31
+	<section>
32
+	<title>LRKProxy Architecture</title>
33
+	<section>
34
+		<title>LRKP_Controlling Layer (LRKP_CL)</title>
35
+		<para>
36
+			The first layer is developed as User-Space
37
+			application that allows User-Space to directly
38
+			access and manipulate cache data
39
+			buffer and packet buffer in Kernel-Space. This layer
40
+			gets all information about creating new sessions,
41
+			active sessions and tear-down sessions which is
42
+	       		gotten from SDP body during signaling plan and relay
43
+			them to the LRKP-Transport Stateful Layer (LRKP-
44
+			TSL).
45
+		</para>
46
+	</section>
47
+	<section>
48
+		<title>LRKP_Transport Stateful Layer (LRKP_TSL)</title>
49
+		<para>
50
+			The second layer is developed in Kernel-Space as
51
+        		a main decision point for RTP admission controller
52
+        		and Quickpath selector to where a received packet
53
+        		should be forwarded with power of packet mangling
54
+        		framework in the network stack.
55
+		</para>
56
+	</section>
57
+	<para>
58
+		The LRKP_CL and LRKP-TSL could be run as
59
+		independence functions on different machines. We
60
+		could have one LRKP_CL with multiple LRKP-TSL
61
+		on different machines. The LRKP_CL could works
62
+		with all LRKP-TSL with different strategies(lrkp_alg parameter).
63
+	</para>
64
+	</section>
65
+	<section>
66
+	<title>Multiple LRKProxy usage</title>
67
+	<para>
68
+		The LRKP_CL Layer can support multiple LRKP_TSL Layer
69
+    		for balancing/distribution and control/selection purposes.
70
+	</para>
71
+	<para>
72
+		The module allows definition of several sets of LRKP_TSL.
73
+		Load-balancing will be performed over predefine algorithm by setting lrkp_alg parameter.
74
+
75
+	</para>
76
+	<para>
77
+		IMPORTANT: This module does not support balancing inside a set like as is done RTPProxy module based on
78
+		the weight of each rtpproxy from the set. The balancing would be run on different machine
79
+	</para>
80
+	</section>
81
+	
82
+	<section>
83
+	<title>Dependencies</title>
84
+	<section>
85
+		<title>&kamailio; Modules</title>
86
+		<para>
87
+		The following modules must be loaded before this module:
88
+			<itemizedlist>
89
+			<listitem>
90
+			<para>
91
+				<emphasis>tm module</emphasis> - (optional) if you want to
92
+				have lrkproxy_manage() fully functional
93
+			</para>
94
+			</listitem>
95
+			</itemizedlist>
96
+		</para>
97
+	</section>
98
+	<section>
99
+		<title>External Libraries or Applications</title>
100
+		<para>
101
+		The following libraries or applications must be installed before
102
+		running &kamailio; with this module loaded:
103
+			<itemizedlist>
104
+			<listitem>
105
+			<para>
106
+				<emphasis>None</emphasis>.
107
+			</para>
108
+			</listitem>
109
+			</itemizedlist>
110
+		</para>
111
+	</section>
112
+	<section>
113
+	<title>Parameters</title>
114
+	<section id="lrkproxy.p.lrkproxy_sock">
115
+	<title><varname>lrkproxy_sock</varname> (string)</title>
116
+			<para>
117
+			Used to define the list of LRKP_TSL instances to connect to. These can
118
+			be UNIX sockets or IPv4/IPv6 UDP sockets. Each modparam entry will
119
+   			insert sockets into a single set with default value set ID '0'.
120
+   			To define multiple LRKP_TSL, just add the instances in each modparam.
121
+			</para>
122
+			<para>
123
+			<emphasis>
124
+				Default value is <quote>NONE</quote> (disabled).
125
+			</emphasis>
126
+			</para>
127
+			<example>
128
+			<title>Set <varname>lrkproxy_sock</varname> parameter</title>
129
+			<programlisting format="linespecific">
130
+...
131
+# single lrkproxy
132
+modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.108:8080")
133
+
134
+# multiple lrkproxies for LB in diffenrent machine
135
+modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.108:8080")
136
+modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.109:8080")
137
+
138
+...
139
+</programlisting>
140
+		</example>
141
+	</section>
142
+	<section id="lrkproxy.p.lrkproxy_disable_tout">
143
+		<title><varname>lrkproxy_disable_tout</varname> (integer)</title>
144
+		<para>
145
+		Once LRKP_TSL was found unreachable and marked as disabled, the
146
+   		LRKP_CL module will not attempt to establish communication to LRKP_TSL
147
+   		for lrkproxy_disable_tout seconds.
148
+		</para>
149
+		<para>
150
+		<emphasis>
151
+			Default value is <quote>60</quote>.
152
+		</emphasis>
153
+		</para>
154
+		<example>
155
+		<title>Set <varname>lrkproxy_disable_tout</varname> parameter</title>
156
+		<programlisting format="linespecific">
157
+...
158
+modparam("lrkproxy", "lrkproxy_disable_tout", 20)
159
+...
160
+</programlisting>
161
+		</example>
162
+	</section>
163
+	<section id="lrkproxy.p.lrkproxy_tout">
164
+		<title><varname>lrkproxy_tout</varname> (integer)</title>
165
+		<para>
166
+		Timeout value in waiting for reply from LRKP_TSL.
167
+		</para>
168
+		<para>
169
+		<emphasis>
170
+			Default value is <quote>1</quote>.
171
+		</emphasis>
172
+		</para>
173
+		<example>
174
+		<title>Set <varname>lrkproxy_tout</varname> parameter</title>
175
+		<programlisting format="linespecific">
176
+...
177
+modparam("lrkproxy", "lrkproxy_tout", 2)
178
+...
179
+</programlisting>
180
+		</example>
181
+	</section>
182
+	<section id="lrkproxy.p.lrkproxy_retr">
183
+		<title><varname>lrkproxy_retr</varname> (integer)</title>
184
+		<para>
185
+		How many times the LRKP_CL should retry to send and receive after
186
+		timeout was generated.
187
+		</para>
188
+		<para>
189
+		<emphasis>
190
+			Default value is <quote>5</quote>.
191
+		</emphasis>
192
+		</para>
193
+		<example>
194
+		<title>Set <varname>lrkproxy_retr</varname> parameter</title>
195
+		<programlisting format="linespecific">
196
+...
197
+modparam("lrkproxy", "lrkproxy_retr", 2)
198
+...
199
+</programlisting>
200
+		</example>
201
+	</section>
202
+	<section id="lrkproxy.p.lrkp_alg">
203
+		<title><varname>lrkp_alg</varname> (integer)</title>
204
+		<para>
205
+		This parameter set the algorithm of LRKP_TSL selection.
206
+    		lrk_LINER=0,
207
+    		lrk_RR=1
208
+		</para>
209
+		<para>
210
+		<emphasis>
211
+			Default value is <quote>0</quote>.
212
+		</emphasis>
213
+		</para>
214
+		<example>
215
+		<title>Set <varname>lrkp_alg</varname> parameter</title>
216
+		<programlisting format="linespecific">
217
+...
218
+modparam("lrkproxy", "lrkp_alg", 1)
219
+...
220
+</programlisting>
221
+		</example>
222
+	</section>
223
+
224
+	<section id="lrkproxy.p.hash_table_tout">
225
+		<title><varname>hash_table_tout</varname> (integer)</title>
226
+		<para>
227
+		Number of seconds after an lrkproxy hash table entry is marked for
228
+   		deletion. By default, this parameter is set to 3600 (seconds).
229
+		</para>
230
+		<para>
231
+		To maintain information about a selected rtp machine node, for a given
232
+		call, entries are added in a hashtable of (callid, viabranch) pairs. When
233
+   		command comes, lookup callid, viabranch pairs. If found, return chosen node. If not
234
+   		found, choose a new node, insert it in the hastable and return the
235
+   		chosen node.
236
+		</para>
237
+		<para>
238
+		NOTE: In the current implementation, the actual deletion happens on the
239
+		fly, while insert/remove/lookup the hastable, only for the entries in
240
+		the insert/remove/lookup path.
241
+		</para>
242
+		<para>
243
+		NOTE: When configuring this parameter, one should consider maximum call
244
+		time VS share memory for unfinished calls.
245
+		</para>
246
+		<para>
247
+		<emphasis>
248
+			Default value is <quote>3600</quote>.
249
+		</emphasis>
250
+		</para>
251
+		<example>
252
+		<title>Set <varname>hash_table_tout</varname> parameter</title>
253
+		<programlisting format="linespecific">
254
+...
255
+modparam("lrkproxy", "hash_table_tout", "3600")
256
+...
257
+</programlisting>
258
+		</example>
259
+	</section>
260
+	<section id="lrkproxy.p.hash_table_size">
261
+		<title><varname>hash_table_size</varname> (integer)</title>
262
+		<para>
263
+		Size of the hash table. Default value is 128.
264
+		</para>
265
+		<para>
266
+		<emphasis>
267
+			Default value is <quote>128</quote>.
268
+		</emphasis>
269
+		</para>
270
+		<example>
271
+		<title>Set <varname>hash_table_size</varname> parameter</title>
272
+		<programlisting format="linespecific">
273
+...
274
+modparam("lrkproxy", "hash_table_size", 256)
275
+...
276
+</programlisting>
277
+		</example>
278
+	</section>
279
+	</section>
280
+	<section>
281
+	<title>Functions</title>
282
+	<section id="lrkproxy.f.set_lrkproxy_set">
283
+		<title>
284
+		<function moreinfo="none">set_lrkproxy_set(setid)</function>
285
+		</title>
286
+		<para>
287
+		Sets the Id of the lrkproxy set to be used for the next
288
+   		lrkproxy_manage() command. The parameter can be an integer or a config
289
+   		variable holding an integer.
290
+		</para>
291
+		<para>
292
+		This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
293
+		BRANCH_ROUTE.
294
+		</para>
295
+		<example>
296
+		<title><function>set_lrkproxy_set</function> usage</title>
297
+		<programlisting format="linespecific">
298
+...
299
+set_lrkproxy_set("0");
300
+lrkproxy_manage();
301
+...
302
+</programlisting>
303
+		</example>
304
+	</section>
305
+        <section id="lrkproxy.f.lrkproxy_manage">
306
+                <title>
307
+                <function moreinfo="none">lrkproxy_manage([flags [, ip_address]])</function>
308
+                </title>
309
+                <para>
310
+                Manage the LRKProxy session - it combines the functionality of
311
+   		lrkproxy_offer(), lrkproxy_answer() and unforce_lrkproxy(), detecting
312
+   		internally based on message type and method which one to execute.
313
+                </para>
314
+		<para>
315
+		   IMPORTANT:The LRKProxy just has one function relating rtp packets. 
316
+		   It does not support combination of functionality of lrkproxy_offer(),
317
+		   lrkproxy_answer() and unforce_lrkproxy() and other etc.
318
+		   So you have to just use lrkproxy_manage.
319
+		</para>
320
+		<para>Meaning of the parameters is as follows:</para>
321
+		<itemizedlist>
322
+		<listitem>
323
+			<para>
324
+			<emphasis>flags</emphasis> - flags to turn on some features.
325
+			</para>
326
+			<itemizedlist>
327
+				<listitem><para>
328
+				<emphasis>internal,external</emphasis> - The shorthand of this flag is "ie".
329
+				This can be used to relay media sessions between two different NIC from internal to external path.
330
+				</para></listitem>
331
+			</itemizedlist>
332
+			<itemizedlist>
333
+				<listitem><para>
334
+				<emphasis>external,internal</emphasis> - The shorthand of this flag is "ei".
335
+				This can be used to relay media sessions between two different NIC from external to internal path.
336
+				</para></listitem>
337
+			</itemizedlist>
338
+		</listitem>
339
+		<listitem><para>
340
+		<emphasis>ip_address</emphasis> - new SDP IP address.This optional parameter is under development.
341
+		</para></listitem>
342
+		</itemizedlist>
343
+		<para>
344
+		This function can be used from ANY_ROUTE.
345
+                </para>
346
+		<example>
347
+		<title><function>lrkproxy_manage</function> usage</title>
348
+		<programlisting format="linespecific">
349
+...
350
+lrkproxy_manage();
351
+//or
352
+lrkproxy_manage("ie");
353
+//or
354
+lrkproxy_manage("ei");
355
+
356
+...
357
+</programlisting>
358
+                </example>
359
+	</section>
360
+
361
+
362
+	</section>
363
+	</section>
364
+</chapter>
0 365
new file mode 100644
... ...
@@ -0,0 +1,1732 @@
1
+/*
2
+ * Copyright (C) 2003-2008 Sippy Software, Inc., http://www.sippysoft.com
3
+ * Copyright (C) 2020 Mojtaba Esfandiari.S, Nasim-Telecom
4
+ *
5
+ * This file is part of Kamailio, a free SIP server.
6
+ *
7
+ * Kamailio is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * Kamailio is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
+ *
21
+ */
22
+
23
+#include <sys/types.h>
24
+#include <sys/socket.h>
25
+#include <sys/time.h>
26
+#include <netinet/in.h>
27
+#include <netinet/in_systm.h>
28
+#ifndef __USE_BSD
29
+#define  __USE_BSD
30
+#endif
31
+#include <netinet/ip.h>
32
+#ifndef __FAVOR_BSD
33
+#define __FAVOR_BSD
34
+#endif
35
+#include <netinet/udp.h>
36
+#include <arpa/inet.h>
37
+#include <sys/uio.h>
38
+#include <sys/un.h>
39
+#include <ctype.h>
40
+#include <errno.h>
41
+#include <netdb.h>
42
+#include <poll.h>
43
+#include <stdio.h>
44
+#include <stdlib.h>
45
+#include <string.h>
46
+#include <unistd.h>
47
+
48
+#include "../../core/flags.h"
49
+#include "../../core/sr_module.h"
50
+#include "../../core/dprint.h"
51
+#include "../../core/data_lump.h"
52
+#include "../../core/data_lump_rpl.h"
53
+#include "../../core/error.h"
54
+#include "../../core/forward.h"
55
+#include "../../core/mem/mem.h"
56
+#include "../../core/parser/parse_from.h"
57
+#include "../../core/parser/parse_to.h"
58
+#include "../../core/parser/parse_uri.h"
59
+#include "../../core/parser/parser_f.h"
60
+#include "../../core/parser/sdp/sdp.h"
61
+#include "../../core/resolve.h"
62
+#include "../../core/timer.h"
63
+#include "../../core/trim.h"
64
+#include "../../core/ut.h"
65
+#include "../../core/pt.h"
66
+#include "../../core/timer_proc.h"
67
+#include "../../core/rpc.h"
68
+#include "../../core/rpc_lookup.h"
69
+#include "../../core/pvar.h"
70
+#include "../../core/lvalue.h"
71
+#include "../../core/msg_translator.h"
72
+#include "../../core/usr_avp.h"
73
+#include "../../core/socket_info.h"
74
+#include "../../core/mod_fix.h"
75
+#include "../../core/dset.h"
76
+#include "../../core/route.h"
77
+#include "../../core/kemi.h"
78
+#include "../../modules/tm/tm_load.h"
79
+#include "lrkproxy.h"
80
+#include "lrkproxy_hash.h"
81
+#include "lrkproxy_funcs.h"
82
+
83
+MODULE_VERSION
84
+
85
+
86
+#if !defined(AF_LOCAL)
87
+#define	AF_LOCAL AF_UNIX
88
+#endif
89
+#if !defined(PF_LOCAL)
90
+#define	PF_LOCAL PF_UNIX
91
+#endif
92
+
93
+///* NAT UAC test constants */
94
+//#define	NAT_UAC_TEST_C_1918	0x01
95
+//#define	NAT_UAC_TEST_RCVD	0x02
96
+//#define	NAT_UAC_TEST_V_1918	0x04
97
+//#define	NAT_UAC_TEST_S_1918	0x08
98
+//#define	NAT_UAC_TEST_RPORT	0x10
99
+
100
+#define DEFAULT_LRKP_SET_ID		0
101
+static str DEFAULT_LRKP_SET_ID_STR = str_init("0");
102
+
103
+//#define RPC_DEFAULT_NATPING_STATE	1
104
+
105
+#define RPC_MIN_RECHECK_TICKS		0
106
+#define RPC_MAX_RECHECK_TICKS		(unsigned int)-1
107
+
108
+
109
+/* Supported version of the LRK proxy command protocol */
110
+#define	SUP_CPROTOVER	"20190708"
111
+/* Required additional version of the LRK proxy command protocol */
112
+#define	REQ_CPROTOVER	"20190709"
113
+/* Additional version necessary for re-packetization support */
114
+#define	REP_CPROTOVER	"20190708"
115
+#define	PTL_CPROTOVER	"20190708"
116
+
117
+#define	CPORT		"22333"
118
+#define HASH_SIZE   128
119
+
120
+static char *gencookie();
121
+static int lrkp_test(struct lrkp_node*);
122
+static int lrkp_get_config(struct lrkp_node *node);
123
+static int lrkp_set_conntrack_rule(struct lrkproxy_hash_entry *e);
124
+
125
+
126
+static int lrkproxy_force(struct sip_msg *msg, const char *flags, enum lrk_operation op, int more);
127
+static int lrkproxy_unforce(struct sip_msg *msg, const char *flags, enum lrk_operation op, int more);
128
+
129
+static int lrkproxy_manage0(struct sip_msg *msg, char *flags, char *ip);
130
+static int lrkproxy_manage1(struct sip_msg *msg, char *flags, char *ip);
131
+static int lrkproxy_manage2(struct sip_msg *msg, char *flags, char *ip);
132
+
133
+static int change_media_sdp(sip_msg_t *msg, struct lrkproxy_hash_entry *e, const char *flags, enum lrk_operation op);
134
+
135
+static int add_lrkproxy_socks(struct lrkp_set * lrkp_list, char * lrkproxy);
136
+static int fixup_set_id(void ** param, int param_no);
137
+static int set_lrkproxy_set_f(struct sip_msg * msg, char * str1, char * str2);
138
+
139
+static struct lrkp_set * select_lrkp_set(int id_set);
140
+
141
+static int lrkproxy_set_store(modparam_t type, void * val);
142
+static int lrkproxy_add_lrkproxy_set( char * lrk_proxies);
143
+
144
+static int mod_init(void);
145
+static int child_init(int);
146
+static void mod_destroy(void);
147
+
148
+/* Pseudo-Variables */
149
+//static int pv_get_lrkstat_f(struct sip_msg *, pv_param_t *, pv_value_t *);
150
+
151
+static int lrkproxy_disable_tout = 60;
152
+static int lrkproxy_retr = 5;
153
+static int lrkproxy_tout = 1;
154
+static pid_t mypid;
155
+static unsigned int myseqn = 0;
156
+//static str nolrkproxy_str = str_init("a=nolrkproxy:yes");
157
+//static str extra_id_pv_param = {NULL, 0};
158
+
159
+static char ** lrkp_strings=0;
160
+static int lrkp_sets=0; /*used in lrkproxy_set_store()*/
161
+static int lrkp_set_count = 0;
162
+static unsigned int current_msg_id = (unsigned int)-1;
163
+/* LRK proxy balancing list */
164
+struct lrkp_set_head * lrkp_set_list =0;
165
+struct lrkp_set * selected_lrkp_set =0;
166
+struct lrkp_set * default_lrkp_set=0;
167
+struct lrkp_node *selected_lrkp_node = 0;
168
+int lrkp_algorithm = LRK_LINER;
169
+static int hash_table_size = 0;
170
+static int hash_table_tout = 3600;
171
+
172
+
173
+
174
+//static char *ice_candidate_priority_avp_param = NULL;
175
+//static int ice_candidate_priority_avp_type;
176
+//static int_str ice_candidate_priority_avp;
177
+//static str lrk_inst_pv_param = {NULL, 0};
178
+//static pv_spec_t *lrk_inst_pvar = NULL;
179
+
180
+/* array with the sockets used by lrkproxy (per process)*/
181
+static unsigned int lrkp_no = 0;
182
+static int *lrkp_socks = 0;
183
+
184
+
185
+typedef struct lrkp_set_link {
186
+	struct lrkp_set *rset;
187
+	pv_spec_t *rpv;
188
+} lrkp_set_link_t;
189
+
190
+/* tm */
191
+static struct tm_binds tmb;
192
+
193
+/*0-> disabled, 1 ->enabled*/
194
+//unsigned int *natping_state=0;
195
+
196
+static cmd_export_t cmds[] = {
197
+
198
+        {"set_lrkproxy_set",  (cmd_function)set_lrkproxy_set_f,    1,
199
+                fixup_set_id, 0,
200
+                ANY_ROUTE},
201
+        {"lrkproxy_manage",	(cmd_function)lrkproxy_manage0,     0,
202
+                                                       0, 0,
203
+                   ANY_ROUTE},
204
+        {"lrkproxy_manage",	(cmd_function)lrkproxy_manage1,     1,
205
+                                                       fixup_spve_null, fixup_free_spve_null,
206
+                   ANY_ROUTE},
207
+        {"lrkproxy_manage",	(cmd_function)lrkproxy_manage2,     2,
208
+                                                       fixup_spve_spve, fixup_free_spve_spve,
209
+                   ANY_ROUTE},
210
+
211
+        {0, 0, 0, 0, 0, 0}
212
+};
213
+
214
+static param_export_t params[] = {
215
+        {"lrkproxy_sock",         PARAM_STRING|USE_FUNC_PARAM,
216
+                (void*)lrkproxy_set_store          },
217
+        {"lrkproxy_disable_tout", INT_PARAM, &lrkproxy_disable_tout },
218
+        {"lrkproxy_retr",         INT_PARAM, &lrkproxy_retr         },
219
+        {"lrkproxy_tout",         INT_PARAM, &lrkproxy_tout         },
220
+        {"lrkp_alg",         INT_PARAM, &lrkp_algorithm         },
221
+        {"hash_table_tout",       INT_PARAM, &hash_table_tout        },
222
+        {"hash_table_size",       INT_PARAM, &hash_table_size        },
223
+
224
+        {0, 0, 0}
225
+};
226
+
227
+/** module exports */
228
+struct module_exports exports= {
229
+        "lrkproxy",        /* module name */
230
+        DEFAULT_DLFLAGS, /* dlopen flags */
231
+        cmds,            /* cmd exports */
232
+        params,          /* param exports */
233
+        0,               /* RPC method exports */
234
+        0,         /* exported pseudo-variables */
235
+        0,               /* response handling function */
236
+        mod_init,        /* module initialization function */
237
+        child_init,               /* per-child init function */
238
+        mod_destroy                /* module destroy function */
239
+};
240
+
241
+
242
+static int lrkproxy_set_store(modparam_t type, void * val){
243
+
244
+    char * p;
245
+    int len;
246
+
247
+    p = (char* )val;
248
+
249
+    if(p==0 || *p=='\0'){
250
+        return 0;
251
+    }
252
+
253
+    if(lrkp_sets==0){
254
+        lrkp_strings = (char**)pkg_malloc(sizeof(char*));
255
+        if(!lrkp_strings){
256
+                    LM_ERR("no pkg memory left\n");
257
+            return -1;
258
+        }
259
+    } else {/*realloc to make room for the current set*/
260
+        lrkp_strings = (char**)pkg_reallocxf(lrkp_strings,
261
+                                             (lrkp_sets+1)* sizeof(char*));
262
+        if(!lrkp_strings){
263
+                    LM_ERR("no pkg memory left\n");
264
+            return -1;
265
+        }
266
+    }
267
+
268
+    /*allocate for the current set of urls*/
269
+    len = strlen(p);
270
+    lrkp_strings[lrkp_sets] = (char*)pkg_malloc((len+1)*sizeof(char));
271
+
272
+    if(!lrkp_strings[lrkp_sets]){
273
+                LM_ERR("no pkg memory left\n");
274
+        return -1;
275
+    }
276
+
277
+    memcpy(lrkp_strings[lrkp_sets], p, len);
278
+    lrkp_strings[lrkp_sets][len] = '\0';
279
+    lrkp_sets++;
280
+
281
+    return 0;
282
+}
283
+
284
+struct lrkp_set *get_lrkp_set(str *const set_name)
285
+{
286
+    unsigned int this_set_id;
287
+    struct lrkp_set *lrkp_list;
288
+    if (lrkp_set_list == NULL)
289
+    {
290
+                LM_ERR("lrkp set list not configured\n");
291
+        return NULL;
292
+    }
293
+    /* Only integer set_names are valid at the moment */
294
+    if ((set_name->s == NULL) || (set_name->len == 0))
295
+    {
296
+                LM_ERR("Invalid set name '%.*s'\n", set_name->len, set_name->s);
297
+        return NULL;
298
+    }
299
+    if (str2int(set_name, &this_set_id) < 0)
300
+    {
301
+                LM_ERR("Invalid set name '%.*s' - must be integer\n", set_name->len, set_name->s);
302
+        return NULL;
303
+    }
304
+
305
+    lrkp_list = select_lrkp_set(this_set_id);
306
+
307
+    if(lrkp_list==NULL){	/*if a new id_set : add a new set of lrkp*/
308
+        lrkp_list = shm_malloc(sizeof(struct lrkp_set));
309
+        if(!lrkp_list){
310
+                    LM_ERR("no shm memory left\n");
311
+            return NULL;
312
+        }
313
+        memset(lrkp_list, 0, sizeof(struct lrkp_set));
314
+        lrkp_list->id_set = this_set_id;
315
+        if (lrkp_set_list->lset_first == NULL)
316
+        {
317
+            lrkp_set_list->lset_first = lrkp_list;
318
+        } else {
319
+            lrkp_set_list->lset_last->lset_next = lrkp_list;
320
+        }
321
+        lrkp_set_list->lset_last = lrkp_list;
322
+        lrkp_set_count++;
323
+
324
+        if (this_set_id == DEFAULT_LRKP_SET_ID)
325
+        {
326
+            default_lrkp_set = lrkp_list;
327
+        }
328
+    }
329
+    return lrkp_list;
330
+}
331
+
332
+int insert_lrkp_node(struct lrkp_set *const lrkp_list, const str *const url, const int weight, const int enable)
333
+{
334
+    struct lrkp_node *pnode;
335
+
336
+    if ((pnode = shm_malloc(sizeof(struct lrkp_node) + url->len + 1)) == NULL)
337
+    {
338
+                LM_ERR("out of shm memory\n");
339
+        return -1;
340
+    }
341
+
342
+    memset(pnode, 0, sizeof(struct lrkp_node) + url->len + 1);
343
+
344
+
345
+    struct lrkp_node_conf *node_conf;
346
+    node_conf = shm_malloc(sizeof(struct lrkp_node_conf));
347
+    if (!node_conf)
348
+    {
349
+                LM_ERR("out of shm memory\n");
350
+        return -1;
351
+    }
352
+
353
+    memset(node_conf, 0, sizeof(struct lrkp_node_conf));
354
+    pnode->lrkp_n_c = node_conf;
355
+
356
+    pnode->idx = lrkp_no++;
357
+    pnode->ln_weight = weight;
358
+    pnode->ln_umode = 0;
359
+    pnode->ln_enable = enable;
360
+    /* Permanently disable if marked as disabled */
361
+//    pnode->ln_recheck_ticks = disabled ? RPC_MAX_RECHECK_TICKS : 0;
362
+    pnode->ln_url.s = (char*)(pnode + 1);
363
+    memcpy(pnode->ln_url.s, url->s, url->len);
364
+    pnode->ln_url.len = url->len;
365
+
366
+            LM_DBG("url is '%.*s'\n", pnode->ln_url.len, pnode->ln_url.s);
367
+
368
+    /* Find protocol and store address */
369
+    pnode->ln_address = pnode->ln_url.s;
370
+    if (strncasecmp(pnode->ln_address, "udp:", 4) == 0) {
371
+        pnode->ln_umode = 1;
372
+        pnode->ln_address += 4;
373
+    } else if (strncasecmp(pnode->ln_address, "udp6:", 5) == 0) {
374
+        pnode->ln_umode = 6;
375
+        pnode->ln_address += 5;
376
+    } else if (strncasecmp(pnode->ln_address, "unix:", 5) == 0) {
377
+        pnode->ln_umode = 0;
378
+        pnode->ln_address += 5;
379
+    }
380
+
381
+    if (lrkp_list->ln_first == NULL)
382
+    {
383
+        lrkp_list->ln_first = pnode;
384
+    } else {
385
+        lrkp_list->ln_last->ln_next = pnode;
386
+    }
387
+    lrkp_list->ln_last = pnode;
388
+    lrkp_list->lrkp_node_count++;
389
+
390
+    return 0;
391
+}
392
+
393
+static int add_lrkproxy_socks(struct lrkp_set * lrkp_list,
394
+                              char * lrkproxy){
395
+    /* Make lrk proxies list. */
396
+    char *p, *p1, *p2, *plim;
397
+    int weight;
398
+    str url;
399
+
400
+    p = lrkproxy;
401
+    plim = p + strlen(p);
402
+
403
+    for(;;) {
404
+        weight = 1;
405
+        while (*p && isspace((int)*p))
406
+            ++p;
407
+        if (p >= plim)
408
+            break;
409
+        p1 = p;
410
+        while (*p && !isspace((int)*p))
411
+            ++p;
412
+        if (p <= p1)
413
+            break; /* may happen??? */
414
+        /* Have weight specified? If yes, scan it */
415
+        p2 = memchr(p1, '=', p - p1);
416
+        if (p2 != NULL) {
417
+            weight = strtoul(p2 + 1, NULL, 10);
418
+        } else {
419
+            p2 = p;
420
+        }
421
+
422
+        url.s = p1;
423
+        url.len = (p2-p1);
424
+        insert_lrkp_node(lrkp_list, &url, weight, 0);
425
+    }
426
+    return 0;
427
+}
428
+
429
+/*	0-succes
430
+ *  -1 - erorr
431
+ * */
432
+static int lrkproxy_add_lrkproxy_set( char * lrk_proxies)
433
+{
434
+    char *p,*p2;
435
+    struct lrkp_set * lrkp_list;
436
+    str id_set;
437
+
438
+    /* empty definition? */
439
+    p= lrk_proxies;
440
+    if(!p || *p=='\0'){
441
+        return 0;
442
+    }
443
+
444
+    for(;*p && isspace(*p);p++);
445
+    if(*p=='\0'){
446
+        return 0;
447
+    }
448
+
449
+    lrk_proxies = strstr(p, "==");
450
+    if(lrk_proxies){
451
+        if(*(lrk_proxies +2)=='\0'){
452
+                    LM_ERR("script error -invalid lrk proxy list!\n");
453
+            return -1;
454
+        }
455
+
456
+        *lrk_proxies = '\0';
457
+        p2 = lrk_proxies-1;
458
+        for(;isspace(*p2); *p2 = '\0',p2--);
459
+        id_set.s = p;	id_set.len = p2 - p+1;
460
+
461
+        if(id_set.len <= 0){
462
+                    LM_ERR("script error -invalid set_id value!\n");
463
+            return -1;
464
+        }
465
+
466
+        lrk_proxies+=2;
467
+    }else{
468
+        lrk_proxies = p;
469
+        id_set = DEFAULT_LRKP_SET_ID_STR;
470
+    }
471
+
472
+    for(;*lrk_proxies && isspace(*lrk_proxies);lrk_proxies++);
473
+
474
+    if(!(*lrk_proxies)){
475
+                LM_ERR("script error -empty lrkproxy list\n");
476
+        return -1;;
477
+    }
478
+
479
+    lrkp_list = get_lrkp_set(&id_set);
480
+    if (lrkp_list == NULL)
481
+    {
482
+                LM_ERR("Failed to get or create lrkp_list for '%.*s'\n", id_set.len, id_set.s);
483
+        return -1;
484
+    }
485
+
486
+    if(add_lrkproxy_socks(lrkp_list, lrk_proxies)!= 0){
487
+        return -1;
488
+    }
489
+
490
+    return 0;
491
+}
492
+
493
+
494
+static int fixup_set_id(void ** param, int param_no)
495
+{
496
+	int int_val, err;
497
+	struct lrkp_set* lrkp_list;
498
+	lrkp_set_link_t *lrkl = NULL;
499
+	str s;
500
+
501
+	lrkl = (lrkp_set_link_t*)pkg_malloc(sizeof(lrkp_set_link_t));
502
+	if(lrkl==NULL) {
503
+		LM_ERR("no more pkg memory\n");
504
+		return -1;
505
+	}
506
+	memset(lrkl, 0, sizeof(lrkp_set_link_t));
507
+	s.s = (char*)*param;
508
+	s.len = strlen(s.s);
509
+
510
+	if(s.s[0] == PV_MARKER) {
511
+		int_val = pv_locate_name(&s);
512
+		if(int_val<0 || int_val!=s.len) {
513
+			LM_ERR("invalid parameter %s\n", s.s);
514
+			pkg_free(lrkl);
515
+			return -1;
516
+		}
517
+		lrkl->rpv = pv_cache_get(&s);
518
+		if(lrkl->rpv == NULL) {
519
+			LM_ERR("invalid pv parameter %s\n", s.s);
520
+			pkg_free(lrkl);
521
+			return -1;
522
+		}
523
+	} else {
524
+		int_val = str2s(*param, strlen(*param), &err);
525
+		if (err == 0) {
526
+			pkg_free(*param);
527
+			if((lrkp_list = select_lrkp_set(int_val)) ==0){
528
+				LM_ERR("lrkp_proxy set %i not configured\n", int_val);
529
+				pkg_free(lrkl);
530
+				return E_CFG;
531
+			}
532
+			lrkl->rset = lrkp_list;
533
+		} else {
534
+			LM_ERR("bad number <%s>\n",	(char *)(*param));
535
+			pkg_free(lrkl);
536
+			return E_CFG;
537
+		}
538
+	}
539
+	*param = (void*)lrkl;
540
+	return 0;
541
+}
542
+
543
+
544
+static int
545
+mod_init(void)
546
+{
547
+    int i;
548
+//	pv_spec_t avp_spec;
549
+//	str s;
550
+//	unsigned short avp_flags;
551
+
552
+//	if(lrkproxy_rpc_init()<0)
553
+//	{
554
+//		LM_ERR("failed to register RPC commands\n");
555
+//		return -1;
556
+//	}
557
+
558
+    /* Configure the head of the lrkp_set_list */
559
+    lrkp_set_list = shm_malloc(sizeof(struct lrkp_set_head));
560
+    if (lrkp_set_list == NULL)
561
+    {
562
+                LM_ERR("no shm memory for lrkp_set_list\n");
563
+        return -1;
564
+    }
565
+    memset(lrkp_set_list, 0, sizeof(struct lrkp_set_head));
566
+
567
+
568