16319d1d050b266100cb16353e829e54bb52ec66
[sip-router] / src / modules / app_lua / app_lua_api.c
1 /**
2  * Copyright (C) 2010-2016 Daniel-Constantin Mierla (asipto.com)
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <sys/stat.h>
26
27 #include "../../core/sr_module.h"
28 #include "../../core/dprint.h"
29 #include "../../core/ut.h"
30 #include "../../core/mem/mem.h"
31 #include "../../core/locking.h"
32 #include "../../core/data_lump.h"
33 #include "../../core/data_lump_rpl.h"
34 #include "../../core/strutils.h"
35
36 #include "app_lua_api.h"
37 #include "app_lua_sr.h"
38 #include "app_lua_exp.h"
39
40
41 #define SRVERSION "1.0"
42
43 /**
44  * reload enabled param
45  * default: 0 (off)
46  */
47 static unsigned int _app_lua_sr_reload = 1;
48 /**
49  *
50  */
51 static sr_lua_env_t _sr_L_env;
52
53 /**
54  *
55  */
56 static int *_app_lua_sv = NULL;
57
58 /**
59  * @return the static Lua env
60  */
61 sr_lua_env_t *sr_lua_env_get(void)
62 {
63         return &_sr_L_env;
64 }
65
66 /**
67  *
68  */
69 static sr_lua_load_t *_sr_lua_load_list = NULL;
70 /**
71  * set of locks to manage the shared variable.
72  */
73 static gen_lock_set_t *sr_lua_locks = NULL;
74 static sr_lua_script_ver_t *sr_lua_script_ver = NULL;
75
76
77 int lua_sr_alloc_script_ver(void)
78 {
79         int size = _sr_L_env.nload;
80
81         sr_lua_script_ver = (sr_lua_script_ver_t *) shm_malloc(sizeof(sr_lua_script_ver_t));
82         if(sr_lua_script_ver==NULL)
83         {
84                 SHM_MEM_ERROR;
85                 return -1;
86         }
87
88         sr_lua_script_ver->version = (unsigned int *) shm_malloc(sizeof(unsigned int)*size);
89         if(sr_lua_script_ver->version==NULL)
90         {
91                 SHM_MEM_ERROR;
92                 goto error;
93         }
94         memset(sr_lua_script_ver->version, 0, sizeof(unsigned int)*size);
95         sr_lua_script_ver->len = size;
96
97         if((sr_lua_locks=lock_set_alloc(size))==0)
98         {
99                 LM_CRIT("failed to alloc lock set\n");
100                 goto error;
101         }
102         if(lock_set_init(sr_lua_locks)==0 )
103         {
104                 LM_CRIT("failed to init lock set\n");
105                 goto error;
106         }
107
108         return 0;
109 error:
110         if(sr_lua_script_ver!=NULL)
111         {
112                 if(sr_lua_script_ver->version!=NULL)
113                 {
114                         shm_free(sr_lua_script_ver->version);
115                         sr_lua_script_ver->version = NULL;
116                 }
117                 shm_free(sr_lua_script_ver);
118                 sr_lua_script_ver = NULL;
119         }
120         if(sr_lua_locks!=NULL)
121         {
122                 lock_set_destroy( sr_lua_locks );
123                 lock_set_dealloc( sr_lua_locks );
124                 sr_lua_locks = NULL;
125         }
126         return -1;
127 }
128
129 /**
130  *
131  */
132 int sr_lua_load_script(char *script)
133 {
134         sr_lua_load_t *li;
135
136         li = (sr_lua_load_t*)pkg_malloc(sizeof(sr_lua_load_t));
137         if(li==NULL)
138         {
139                 PKG_MEM_ERROR;
140                 return -1;
141         }
142         memset(li, 0, sizeof(sr_lua_load_t));
143         li->script = script;
144         li->version = 0;
145         li->next = _sr_lua_load_list;
146         _sr_lua_load_list = li;
147         _sr_L_env.nload += 1;
148         LM_DBG("loaded script:[%s].\n", script);
149         LM_DBG("Now there are %d scripts loaded\n", _sr_L_env.nload);
150
151         return 0;
152 }
153
154
155 /**
156  *
157  */
158 int sr_lua_register_module(char *mname)
159 {
160         if(lua_sr_exp_register_mod(mname)==0)
161                 return 0;
162         return -1;
163 }
164
165 /**
166  *
167  */
168 int sr_lua_reload_module(unsigned int reload)
169 {
170         LM_DBG("reload:%d\n", reload);
171         if(reload!=0) {
172                 _app_lua_sr_reload = 1;
173                 LM_DBG("reload param activated!\n");
174         } else {
175                 _app_lua_sr_reload = 0;
176                 LM_DBG("reload param inactivated!\n");
177         }
178         return 0;
179 }
180
181 /**
182  *
183  */
184 void lua_sr_openlibs(lua_State *L)
185 {
186         lua_sr_core_openlibs(L);
187         lua_sr_exp_openlibs(L);
188         lua_sr_kemi_register_libs(L);
189 }
190
191 /**
192  *
193  */
194 int lua_sr_init_mod(void)
195 {
196         /* allocate shm */
197         if(lua_sr_alloc_script_ver()<0)
198         {
199                 LM_CRIT("failed to alloc shm for version\n");
200                 return -1;
201         }
202
203         memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
204         if(lua_sr_exp_init_mod()<0)
205                 return -1;
206
207         return 0;
208
209 }
210
211 /**
212  *
213  */
214 int lua_sr_init_probe(void)
215 {
216         lua_State *L;
217         char *txt;
218         sr_lua_load_t *li;
219         struct stat sbuf;
220
221         L = luaL_newstate();
222         if(L==NULL)
223         {
224                 LM_ERR("cannot open lua\n");
225                 return -1;
226         }
227         luaL_openlibs(L);
228         lua_sr_openlibs(L);
229
230         /* force loading lua lib now */
231         if(luaL_dostring(L, "sr.probe()")!=0)
232         {
233                 txt = (char*)lua_tostring(L, -1);
234                 LM_ERR("error initializing Lua: %s\n", (txt)?txt:"unknown");
235                 lua_pop(L, 1);
236                 lua_close(L);
237                 return -1;
238         }
239
240         /* test if files to be loaded exist */
241         if(_sr_lua_load_list != NULL)
242         {
243                 li = _sr_lua_load_list;
244                 while(li)
245                 {
246                         if(stat(li->script, &sbuf)!=0)
247                         {
248                                 /* file does not exist */
249                                 LM_ERR("cannot find script: %s (wrong path?)\n",
250                                                 li->script);
251                                 lua_close(L);
252                                 return -1;
253                         }
254                         li = li->next;
255                 }
256         }
257         lua_close(L);
258         LM_DBG("Lua probe was ok!\n");
259         return 0;
260 }
261
262 /**
263  *
264  */
265 int lua_sr_init_child(void)
266 {
267         sr_lua_load_t *li;
268         int ret;
269         char *txt;
270
271         memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
272         _sr_L_env.L = luaL_newstate();
273         if(_sr_L_env.L==NULL)
274         {
275                 LM_ERR("cannot open lua\n");
276                 return -1;
277         }
278         luaL_openlibs(_sr_L_env.L);
279         lua_sr_openlibs(_sr_L_env.L);
280
281         /* set SR lib version */
282 #if LUA_VERSION_NUM >= 502
283         lua_pushstring(_sr_L_env.L, SRVERSION);
284         lua_setglobal(_sr_L_env.L, "SRVERSION");
285 #else
286         lua_pushstring(_sr_L_env.L, "SRVERSION");
287         lua_pushstring(_sr_L_env.L, SRVERSION);
288         lua_settable(_sr_L_env.L, LUA_GLOBALSINDEX);
289 #endif
290         if(_sr_lua_load_list != NULL)
291         {
292                 _sr_L_env.LL = luaL_newstate();
293                 if(_sr_L_env.LL==NULL)
294                 {
295                         LM_ERR("cannot open lua loading state\n");
296                         return -1;
297                 }
298                 luaL_openlibs(_sr_L_env.LL);
299                 lua_sr_openlibs(_sr_L_env.LL);
300
301                 /* set SR lib version */
302 #if LUA_VERSION_NUM >= 502
303                 lua_pushstring(_sr_L_env.LL, SRVERSION);
304                 lua_setglobal(_sr_L_env.LL, "SRVERSION");
305 #else
306                 lua_pushstring(_sr_L_env.LL, "SRVERSION");
307                 lua_pushstring(_sr_L_env.LL, SRVERSION);
308                 lua_settable(_sr_L_env.LL, LUA_GLOBALSINDEX);
309 #endif
310                 /* force loading lua lib now */
311                 if(luaL_dostring(_sr_L_env.LL, "sr.probe()")!=0)
312                 {
313                         txt = (char*)lua_tostring(_sr_L_env.LL, -1);
314                         LM_ERR("error initializing Lua: %s\n", (txt)?txt:"unknown");
315                         lua_pop(_sr_L_env.LL, 1);
316                         lua_sr_destroy();
317                         return -1;
318                 }
319
320                 li = _sr_lua_load_list;
321                 while(li)
322                 {
323                         ret = luaL_dofile(_sr_L_env.LL, (const char*)li->script);
324                         if(ret!=0)
325                         {
326                                 LM_ERR("failed to load Lua script: %s (err: %d)\n",
327                                                 li->script, ret);
328                                 txt = (char*)lua_tostring(_sr_L_env.LL, -1);
329                                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
330                                 lua_pop(_sr_L_env.LL, 1);
331                                 lua_sr_destroy();
332                                 return -1;
333                         }
334                         li = li->next;
335                 }
336         }
337         LM_DBG("Lua initialized!\n");
338         return 0;
339 }
340
341 /**
342  *
343  */
344 void lua_sr_destroy(void)
345 {
346         if(_sr_L_env.L!=NULL)
347         {
348                 lua_close(_sr_L_env.L);
349                 _sr_L_env.L = NULL;
350         }
351         if(_sr_L_env.LL!=NULL)
352         {
353                 lua_close(_sr_L_env.LL);
354                 _sr_L_env.LL = NULL;
355         }
356         memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
357
358         if(sr_lua_script_ver!=NULL)
359         {
360                 shm_free(sr_lua_script_ver->version);
361                 shm_free(sr_lua_script_ver);
362         }
363
364         if (sr_lua_locks!=NULL)
365         {
366                 lock_set_destroy( sr_lua_locks );
367                 lock_set_dealloc( sr_lua_locks );
368                 sr_lua_locks = 0;
369         }
370
371         if(_app_lua_sv!=NULL) {
372                 pkg_free(_app_lua_sv);
373                 _app_lua_sv = 0;
374         }
375 }
376
377 /**
378  *
379  */
380 int lua_sr_list_script(sr_lua_load_t **list)
381 {
382         *list = _sr_lua_load_list;
383         return 0;
384 }
385
386 /**
387  * Mark script in pos to be reloaded
388  * pos -1: reload all scritps
389  */
390 int lua_sr_reload_script(int pos)
391 {
392         int i, len = sr_lua_script_ver->len;
393         if(_sr_lua_load_list!= NULL)
394         {
395                 if (!sr_lua_script_ver)
396                 {
397                         LM_CRIT("shm for version not allocated\n");
398                         return -1;
399                 }
400                 if (_app_lua_sr_reload==0)
401                 {
402                         LM_ERR("reload is not activated\n");
403                         return -3;
404                 }
405                 if (pos<0)
406                 {
407                         // let's mark all the scripts to be reloaded
408                         for (i=0;i<len;i++)
409                         {
410                                 lock_set_get(sr_lua_locks, i);
411                                 sr_lua_script_ver->version[i] += 1;
412                                 lock_set_release(sr_lua_locks, i);
413                         }
414                 }
415                 else
416                 {
417                         if (pos>=0 && pos<len)
418                         {
419                                 lock_set_get(sr_lua_locks, pos);
420                                 sr_lua_script_ver->version[pos] += 1;
421                                 lock_set_release(sr_lua_locks, pos);
422                                 LM_DBG("pos: %d set to reloaded\n", pos);
423                         }
424                         else
425                         {
426                                 LM_ERR("pos out of range\n");
427                                 return -2;
428                         }
429                 }
430                 return 0;
431         }
432         LM_ERR("No script loaded\n");
433         return -1;
434 }
435
436 /**
437  * Checks if loaded version matches the shared
438  * counter. If not equal reloads the script.
439  */
440 int sr_lua_reload_script(void)
441 {
442         sr_lua_load_t *li = _sr_lua_load_list;
443         int ret, i;
444         char *txt;
445         int sv_len = sr_lua_script_ver->len;
446
447         if(li==NULL)
448         {
449                 LM_DBG("No script loaded\n");
450                 return 0;
451         }
452
453         if(_app_lua_sv==NULL) {
454                 _app_lua_sv = (int *) pkg_malloc(sizeof(int)*sv_len);
455                 if(_app_lua_sv==NULL)
456                 {
457                         PKG_MEM_ERROR;
458                         return -1;
459                 }
460         }
461
462         for(i=0;i<sv_len;i++)
463         {
464                 lock_set_get(sr_lua_locks, i);
465                 _app_lua_sv[i] = sr_lua_script_ver->version[i];
466                 lock_set_release(sr_lua_locks, i);
467
468                 if(li->version!=_app_lua_sv[i])
469                 {
470                         LM_DBG("loaded version:%d needed: %d Let's reload <%s>\n",
471                                 li->version, _app_lua_sv[i], li->script);
472                         ret = luaL_dofile(_sr_L_env.LL, (const char*)li->script);
473                         if(ret!=0)
474                         {
475                                 LM_ERR("failed to load Lua script: %s (err: %d)\n",
476                                                 li->script, ret);
477                                 txt = (char*)lua_tostring(_sr_L_env.LL, -1);
478                                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
479                                 lua_pop(_sr_L_env.LL, 1);
480                                 return -1;
481                         }
482                         li->version = _app_lua_sv[i];
483                         LM_DBG("<%s> set to version %d\n", li->script, li->version);
484                 }
485                 else LM_DBG("No need to reload [%s] is version %d\n",
486                         li->script, li->version);
487                 li = li->next;
488         }
489         return 1;
490 }
491
492 /**
493  *
494  */
495 int lua_sr_initialized(void)
496 {
497         if(_sr_L_env.L==NULL)
498                 return 0;
499
500         return 1;
501 }
502
503 /**
504  *
505  */
506 int app_lua_return_int(lua_State *L, int v)
507 {
508         lua_pushinteger(L, v);
509         return 1;
510 }
511
512 /**
513  *
514  */
515 int app_lua_return_error(lua_State *L)
516 {
517         lua_pushinteger(L, -1);
518         return 1;
519 }
520
521 /**
522  *
523  */
524 int app_lua_return_boolean(lua_State *L, int b)
525 {
526         if(b==SRLUA_FALSE)
527                 lua_pushboolean(L, SRLUA_FALSE);
528         else
529                 lua_pushboolean(L, SRLUA_TRUE);
530         return 1;
531 }
532
533 /**
534  *
535  */
536 int app_lua_return_false(lua_State *L)
537 {
538         lua_pushboolean(L, SRLUA_FALSE);
539         return 1;
540 }
541
542 /**
543  *
544  */
545 int app_lua_return_true(lua_State *L)
546 {
547         lua_pushboolean(L, SRLUA_TRUE);
548         return 1;
549 }
550
551 /**
552  *
553  */
554 int app_lua_dostring(sip_msg_t *msg, char *script)
555 {
556         int ret;
557         char *txt;
558         sip_msg_t *bmsg;
559
560         LM_DBG("executing Lua string: [[%s]]\n", script);
561         LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
562         bmsg = _sr_L_env.msg;
563         _sr_L_env.msg = msg;
564         ret = luaL_dostring(_sr_L_env.L, script);
565         if(ret!=0)
566         {
567                 txt = (char*)lua_tostring(_sr_L_env.L, -1);
568                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
569                 lua_pop (_sr_L_env.L, 1);
570         }
571         _sr_L_env.msg = bmsg;
572         return (ret==0)?1:-1;
573 }
574
575 /**
576  *
577  */
578 int app_lua_dofile(sip_msg_t *msg, char *script)
579 {
580         int ret;
581         char *txt;
582         sip_msg_t *bmsg;
583
584         LM_DBG("executing Lua file: [[%s]]\n", script);
585         LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
586         bmsg = _sr_L_env.msg;
587         _sr_L_env.msg = msg;
588         ret = luaL_dofile(_sr_L_env.L, script);
589         if(ret!=0)
590         {
591                 txt = (char*)lua_tostring(_sr_L_env.L, -1);
592                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
593                 lua_pop(_sr_L_env.L, 1);
594         }
595         _sr_L_env.msg = bmsg;
596         return (ret==0)?1:-1;
597 }
598
599 /**
600  *
601  */
602 int app_lua_runstring(sip_msg_t *msg, char *script)
603 {
604         int ret;
605         char *txt;
606         sip_msg_t *bmsg;
607
608         if(_sr_L_env.LL==NULL)
609         {
610                 LM_ERR("lua loading state not initialized (call: %s)\n", script);
611                 return -1;
612         }
613
614         LM_DBG("running Lua string: [[%s]]\n", script);
615         LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.LL));
616         bmsg = _sr_L_env.msg;
617         _sr_L_env.msg = msg;
618         ret = luaL_dostring(_sr_L_env.LL, script);
619         if(ret!=0)
620         {
621                 txt = (char*)lua_tostring(_sr_L_env.LL, -1);
622                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
623                 lua_pop (_sr_L_env.LL, 1);
624         }
625         _sr_L_env.msg = bmsg;
626         return (ret==0)?1:-1;
627 }
628
629 /**
630  *
631  */
632 static str _sr_kemi_lua_exit_string = str_init("~~ksr~exit~~");
633
634 /**
635  *
636  */
637 str* sr_kemi_lua_exit_string_get(void)
638 {
639         return &_sr_kemi_lua_exit_string;
640 }
641
642 /**
643  *
644  */
645 int app_lua_run_ex(sip_msg_t *msg, char *func, char *p1, char *p2,
646                 char *p3, int emode)
647 {
648         int n;
649         int ret;
650         str txt;
651         sip_msg_t *bmsg;
652         int ltop;
653
654         if(_sr_L_env.LL==NULL)
655         {
656                 LM_ERR("lua loading state not initialized (call: %s)\n", func);
657                 return -1;
658         }
659         if(_app_lua_sr_reload!=0)
660         {
661                 /* check the script version loaded */
662                 if(!sr_lua_reload_script())
663                 {
664                         LM_ERR("lua reload failed\n");
665                         return -1;
666                 }
667         }
668         else LM_DBG("reload deactivated\n");
669         LM_DBG("executing Lua function: [[%s]]\n", func);
670         ltop = lua_gettop(_sr_L_env.LL);
671         LM_DBG("lua top index is: %d\n", ltop);
672         lua_getglobal(_sr_L_env.LL, func);
673         if(!lua_isfunction(_sr_L_env.LL, -1))
674         {
675                 if(emode) {
676                         LM_ERR("no such function [%s] in lua scripts\n", func);
677                         LM_ERR("top stack type [%d - %s]\n",
678                                 lua_type(_sr_L_env.LL, -1),
679                                 lua_typename(_sr_L_env.LL,lua_type(_sr_L_env.LL, -1)));
680                         txt.s = (char*)lua_tostring(_sr_L_env.LL, -1);
681                         LM_ERR("error from Lua: %s\n", (txt.s)?txt.s:"unknown");
682                         /* restores the original stack size */
683                         lua_settop(_sr_L_env.LL, ltop);
684                         return -1;
685                 } else {
686                         /* restores the original stack size */
687                         lua_settop(_sr_L_env.LL, ltop);
688                         return 1;
689                 }
690         }
691         n = 0;
692         if(p1!=NULL)
693         {
694                 lua_pushstring(_sr_L_env.LL, p1);
695                 n++;
696                 if(p2!=NULL)
697                 {
698                         lua_pushstring(_sr_L_env.LL, p2);
699                         n++;
700                         if(p3!=NULL)
701                         {
702                                 lua_pushstring(_sr_L_env.LL, p3);
703                                 n++;
704                         }
705                 }
706         }
707         bmsg = _sr_L_env.msg;
708         _sr_L_env.msg = msg;
709         ret = lua_pcall(_sr_L_env.LL, n, 0, 0);
710         _sr_L_env.msg = bmsg;
711         if(ret!=0)
712         {
713                 txt.s = (char*)lua_tostring(_sr_L_env.LL, -1);
714                 n = 0;
715                 if(txt.s!=NULL) {
716                         for(n=0; txt.s[n]!='\0' && _sr_kemi_lua_exit_string.s[n]!='\0';
717                                         n++) {
718                                 if(txt.s[n] != _sr_kemi_lua_exit_string.s[n])
719                                         break;
720                         }
721                         if(txt.s[n]!='\0' || _sr_kemi_lua_exit_string.s[n]!='\0') {
722                                 LM_ERR("error from Lua: %s\n", txt.s);
723                                 n = 0;
724                         } else {
725                                 LM_DBG("ksr error call from Lua: %s\n", txt.s);
726                                 n = 1;
727                         }
728                 } else {
729                         LM_ERR("error from Lua: unknown\n");
730                 }
731                 lua_pop(_sr_L_env.LL, 1);
732                 if(n==1) {
733                         /* restores the original stack size */
734                         lua_settop(_sr_L_env.LL, ltop);
735                         return 1;
736                 } else {
737                         LM_ERR("error executing: %s (err: %d)\n", func, ret);
738                         /* restores the original stack size */
739                         lua_settop(_sr_L_env.LL, ltop);
740                         return -1;
741                 }
742         }
743
744         /* restores the original stack size */
745         lua_settop(_sr_L_env.LL, ltop);
746
747         return 1;
748 }
749
750 /**
751  *
752  */
753 int app_lua_run(sip_msg_t *msg, char *func, char *p1, char *p2,
754                 char *p3)
755 {
756         return app_lua_run_ex(msg, func, p1, p2, p3, 1);
757 }
758
759 void app_lua_dump_stack(lua_State *L)
760 {
761         int i;
762         int t;
763         int top;
764
765         top = lua_gettop(L);
766
767         LM_DBG("lua stack top index: %d\n", top);
768         for (i = 1; i <= top; i++)
769         {
770                 t = lua_type(L, i);
771                 switch (t)
772                 {
773                         case LUA_TSTRING:  /* strings */
774                                 LM_DBG("[%i:s> %s\n", i, lua_tostring(L, i));
775                         break;
776                         case LUA_TBOOLEAN:  /* booleans */
777                                 LM_DBG("[%i:b> %s\n", i,
778                                         lua_toboolean(L, i) ? "true" : "false");
779                         break;
780                         case LUA_TNUMBER:  /* numbers */
781                                 LM_DBG("[%i:n> %g\n", i, lua_tonumber(L, i));
782                         break;
783                         default:  /* other values */
784                                 LM_DBG("[%i:t> %s\n", i, lua_typename(L, t));
785                         break;
786                 }
787         }
788 }