Hello,
can you add an extra EoL at the end of the file and try again? iirc, at some point there was an issue counting the #!endif at the end of the file if it was not followed by a new line. I think that was fixed.
Also, kamailio has a cli parameter to print the config after evaluating pre-processor directive, you can use it to see if the result is what you expect to be active in kamailio.cfg
Cheers,
Daniel
Hi,
I am trying to learn Kamailio to set up a SIP/RTP proxy for WebRTC with FreeSWITCH, and I wanted to use this configuration file template as a starting point.
(Source: https://github.com/havfo/WEBRTC-to-SIP)
But i have the error : ERROR: [core/ppcfg.c:275]: pp_ifdef_level_error(): different number of preprocessor directives: 1 more #!if[n]def as #!endifI don't understand because I checked and everything seems okay with the if/endif statements to me.
# grep '#!ifndef' kamailio.cfg | wc -l 2 # grep '#!ifdef' kamailio.cfg | wc -l 49 # grep '#!endif' kamailio.cfg | wc -l 51
And it's ok for chat gpt too :
#!ifdef : 49 occurrences #!ifndef : 2 occurrences Total (#!ifdef and #!ifndef) : 51 occurrences #!endif : 51 occurrences
Is there a problem with the parser or a compatibility problem (i am on 5.6.3) ?Thank.#!KAMAILIO # #!define WITH_MYSQL #!define WITH_AUTH #!define WITH_USRLOCDB #!define WITH_TLS #!define WITH_HOMER #!define WITH_WEBSOCKETS #!define WITH_ANTIFLOOD #!define WITH_IPV6 ##!define WITH_BRIDGE_ON_FAIL #!define WITH_LOCALHOST_WS ##!define WITH_LOCALHOST_SIP #!substdef "!MY_SIP_PORT!5060!g" #!substdef "!MY_SIPS_PORT!5061!g" #!substdef "!MY_WS_PORT!8080!g" #!substdef "!MY_WSS_PORT!4443!g" #!substdef "!MY_IP4_ADDR!XXXXX-XXXXX!g" #!substdef "!IP4_LOCALHOST!127.0.0.1!g" #!substdef "!MY_WS4_ADDR!tcp:MY_IP4_ADDR:MY_WS_PORT!g" #!substdef "!MY_WSS4_ADDR!tls:MY_IP4_ADDR:MY_WSS_PORT!g" #!substdef "!LOCALHOST_WS4_ADDR!tcp:IP4_LOCALHOST:MY_WS_PORT!g" #!substdef "!LOCALHOST_WSS4_ADDR!tls:IP4_LOCALHOST:MY_WSS_PORT!g" #!ifdef WITH_IPV6 #!substdef "!MY_IP6_ADDR![XXXXXX-XXXXXX]!g" #!substdef "!IP6_LOCALHOST![::1]!g" #!substdef "!MY_WS6_ADDR!tcp:MY_IP6_ADDR:MY_WS_PORT!g" #!substdef "!MY_WSS6_ADDR!tls:MY_IP6_ADDR:MY_WSS_PORT!g" #!substdef "!LOCALHOST_WS6_ADDR!tcp:IP6_LOCALHOST:MY_WS_PORT!g" #!substdef "!LOCALHOST_WSS6_ADDR!tls:IP6_LOCALHOST:MY_WSS_PORT!g" #!endif #!substdef "!MY_DOMAIN!XXXX-XXXX!g" # *** Value defines - IDs used later in config #!ifdef WITH_MYSQL # - database URL - used to connect to database server by modules such # as: auth_db, acc, usrloc, a.s.o. #!ifndef DBURL #!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" #!endif #!endif # - flags # FLT_ - per transaction (message) flags # FLB_ - per branch flags #!define FLT_NATS 5 #!define FLB_NATB 6 #!define FLB_NATSIPPING 7 #!define FLB_RTPWS 8 #!define FLB_IPV6 9 #!define FLB_V4V6 10 #!define FLB_BRIDGE 11 ####### Global Parameters ######### ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR #!ifdef WITH_DEBUG debug=4 log_stderror=no #!else debug=2 log_stderror=no #!endif memdbg=5 memlog=5 log_facility=LOG_LOCAL0 fork=yes children=4 port=MY_SIP_PORT tls_port_no=MY_SIPS_PORT #!ifdef WITH_TLS enable_tls=yes #!endif listen=MY_IP4_ADDR #!ifdef WITH_LOCALHOST_SIP listen=IP4_LOCALHOST #!endif #!ifdef WITH_IPV6 listen=MY_IP6_ADDR #!ifdef WITH_LOCALHOST_SIP listen=IP6_LOCALHOST #!endif #!endif #!ifdef WITH_WEBSOCKETS listen=MY_WS4_ADDR #!ifdef WITH_LOCALHOST_WS listen=LOCALHOST_WS4_ADDR #!endif #!ifdef WITH_IPV6 listen=MY_WS6_ADDR #!ifdef WITH_LOCALHOST_WS listen=LOCALHOST_WS6_ADDR #!endif #!endif #!ifdef WITH_TLS listen=MY_WSS4_ADDR #!ifdef WITH_LOCALHOST_WS listen=LOCALHOST_WSS4_ADDR #!endif #!ifdef WITH_IPV6 listen=MY_WSS6_ADDR #!ifdef WITH_LOCALHOST_WS listen=LOCALHOST_WSS6_ADDR #!endif #!endif #!endif #!endif use_dns_cache = on # Use KAMAILIO internal DNS cache use_dns_failover = on # Depends on KAMAILIO internal DNS cache dns_srv_loadbalancing = on # dns_try_naptr = on # dns_retr_time=1 # Time in seconds before retrying a DNS request dns_retr_no=3 # Number of DNS retransmissions before giving up # Set protocol preference order - ignore target priority dns_naptr_ignore_rfc= yes # Ignore target NAPTR priority dns_tls_pref=50 # First priority: TLS dns_tcp_pref=30 # Second priority: TCP dns_udp_pref=10 # Third priority: UDP tcp_connection_lifetime=3604 tcp_accept_no_cl=yes tcp_rd_buf_size=16384 # set paths to location of modules (to sources or installation folders) #!ifdef WITH_SRCPATH mpath="modules/" #!else mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/" #!endif #!ifdef WITH_MYSQL loadmodule "db_mysql.so" #!endif loadmodule "kex.so" loadmodule "corex.so" loadmodule "tm.so" loadmodule "tmx.so" loadmodule "sl.so" loadmodule "rr.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "usrloc.so" loadmodule "registrar.so" loadmodule "textops.so" loadmodule "siputils.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "ctl.so" loadmodule "cfg_rpc.so" loadmodule "sdpops.so" loadmodule "textopsx.so" #!ifdef WITH_AUTH loadmodule "auth.so" loadmodule "auth_db.so" #!ifdef WITH_IPAUTH loadmodule "permissions.so" #!endif #!endif #!ifdef WITH_PRESENCE loadmodule "presence.so" loadmodule "presence_xml.so" #!endif #!ifdef WITH_TLS loadmodule "tls.so" #!endif #!ifdef WITH_HOMER loadmodule "siptrace.so" #!endif #!ifdef WITH_WEBSOCKETS loadmodule "xhttp.so" loadmodule "websocket.so" loadmodule "nathelper.so" loadmodule "rtpengine.so" #!endif #!ifdef WITH_ANTIFLOOD loadmodule "htable.so" loadmodule "pike.so" #!endif #!ifdef WITH_DEBUG loadmodule "debugger.so" #!endif # ----------------- setting module-specific parameters --------------- # ----- rr params ----- # add value to ;lr param to cope with most of the UAs modparam("rr", "enable_full_lr", 1) # do not append from tag to the RR (no need for this script) modparam("rr", "append_fromtag", 0) # ----- registrar params ----- modparam("registrar", "method_filtering", 1) # max value for expires of registrations modparam("registrar", "max_expires", 3600) # ----- usrloc params ----- /* enable DB persistency for location entries */ #!ifdef WITH_USRLOCDB modparam("usrloc", "db_url", DBURL) modparam("usrloc", "db_mode", 2) #!endif # ----- auth_db params ----- #!ifdef WITH_AUTH modparam("auth_db", "db_url", DBURL) modparam("auth_db", "calculate_ha1", 1) modparam("auth_db", "password_column", "password") modparam("auth_db", "load_credentials", "") #!endif #!ifdef WITH_PRESENCE # ----- presence params ----- modparam("presence", "db_url", DBURL) # ----- presence_xml params ----- modparam("presence_xml", "db_url", DBURL) modparam("presence_xml", "force_active", 1) #!endif ##!ifdef WITH_NAT # ----- rtpproxy params ----- modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:22222") modparam("rtpengine", "extra_id_pv", "$avp(extra_id)") # ----- nathelper params ----- modparam("nathelper", "natping_interval", 30) modparam("nathelper", "ping_nated_only", 1) modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) modparam("nathelper", "sipping_from", "sip:pinger@XXXX-XXXX") modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") modparam("usrloc", "nat_bflag", FLB_NATB) ##!endif # ----- corex params ----- modparam("corex", "alias_subdomains", "MY_DOMAIN") #!ifdef WITH_TLS # ----- tls params ----- modparam("tls", "config", "/etc/kamailio/tls.cfg") modparam("tls", "tls_force_run", 1) #!endif #!ifdef WITH_WEBSOCKETS modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") #!endif #!ifdef WITH_HOMER #Siptrace modparam("siptrace", "duplicate_uri", "sip:127.0.0.1:9060") modparam("siptrace", "hep_mode_on", 1) modparam("siptrace", "trace_to_database", 0) modparam("siptrace", "trace_flag", 22) modparam("siptrace", "trace_on", 1) #!endif #!ifdef WITH_ANTIFLOOD # ----- pike params ----- modparam("pike", "sampling_time_unit", 2) modparam("pike", "reqs_density_per_unit", 16) modparam("pike", "remove_latency", 4) # ----- htable params ----- # ip ban htable with autoexpire after 5 minutes modparam("htable", "htable", "ipban=>size=8;autoexpire=300;") #!endif #!ifdef WITH_DEBUG # ----- debugger params ----- modparam("debugger", "cfgtrace", 1) #!endif ####### Routing Logic ######## request_route { #!ifdef WITH_HOMER # start duplicate the SIP message here sip_trace(); setflag(22); #!endif # per request initial checks route(REQINIT); xlog("L_INFO", "START: $rm from $fu (IP:$si:$sp)\n"); #!ifdef WITH_WEBSOCKETS if (nat_uac_test(64)) { # Do NAT traversal stuff for requests from a WebSocket # connection - even if it is not behind a NAT! # This won't be needed in the future if Kamailio and the # WebSocket client support Outbound and Path. force_rport(); if (is_method("REGISTER")) { fix_nated_register(); } else if (!add_contact_alias()) { xlog("L_ERR", "Error aliasing contact <$ct>\n"); sl_send_reply("400", "Bad Request"); exit; } } #!endif # NAT detection route(NATDETECT); # CANCEL processing if (is_method("CANCEL")) { if (t_check_trans()) { route(RELAY); } exit; } # handle requests within SIP dialogs route(WITHINDLG); ### only initial requests (no To tag) t_check_trans(); # authentication route(AUTH); # record routing for dialog forming requests (in case they are routed) # - remove preloaded route headers remove_hf("Route"); if (is_method("INVITE|SUBSCRIBE")) { record_route(); } # dispatch requests to foreign domains route(SIPOUT); ### requests for my local domains # handle presence related requests route(PRESENCE); # handle registrations route(REGISTRAR); if ($rU == $null) { # request with no Username in RURI sl_send_reply("484","Address Incomplete"); exit; } # user location service route(LOCATION); } # Wrapper for relaying requests route[RELAY] { # enable additional event routes for forwarded requests # - serial forking, RTP relaying handling, a.s.o. if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) { if (!t_is_set("branch_route")) { t_on_branch("MANAGE_BRANCH"); } } if (is_method("INVITE|SUBSCRIBE|UPDATE")) { if (!t_is_set("onreply_route")) { t_on_reply("MANAGE_REPLY"); } } if (is_method("INVITE")) { if (!t_is_set("failure_route")) { t_on_failure("MANAGE_FAILURE"); } } if (!t_relay()) { sl_reply_error(); } exit; } # Per SIP request initial checks route[REQINIT] { #!ifdef WITH_ANTIFLOOD # flood dection from same IP and traffic ban for a while # be sure you exclude checking trusted peers, such as pstn gateways # - local host excluded (e.g., loop to self) if (src_ip != myself) { if ($sht(ipban=>$si) != $null) { # ip is already blocked xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n"); exit; } if (!pike_check_req()) { xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n"); $sht(ipban=>$si) = 1; exit; } } #!endif if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; } if (!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } } # Handle requests within SIP dialogs route[WITHINDLG] { if (has_totag()) { # sequential request withing a dialog should # take the path determined by record-routing if (loose_route()) { #!ifdef WITH_WEBSOCKETS if ($du == "") { if (!handle_ruri_alias()) { xlog("L_ERR", "Bad alias <$ru>\n"); sl_send_reply("400", "Bad Request"); exit; } } #!endif route(DLGURI); if (is_method("ACK")) { # ACK is forwarded statelessy route(NATMANAGE); } else if (is_method("NOTIFY")) { # Add Record-Route for in-dialog NOTIFY as per RFC 6665. record_route(); } route(RELAY); } else { if (is_method("SUBSCRIBE") && uri == myself) { # in-dialog subscribe requests route(PRESENCE); exit; } if (is_method("ACK")) { if (t_check_trans()) { # no loose-route, but stateful ACK; # must be an ACK after a 487 # or e.g. 404 from upstream server route(RELAY); exit; } else { # ACK without matching transaction ... ignore and discard exit; } } sl_send_reply("404","Not here"); } exit; } } # Handle SIP registrations route[REGISTRAR] { if (is_method("REGISTER")) { if (isflagset(FLT_NATS)) { setbflag(FLB_NATB); # uncomment next line to do SIP NAT pinging ## setbflag(FLB_NATSIPPING); } #!ifdef WITH_IPV6 if (af == INET6) { setbflag(FLB_IPV6); } #!endif if (!save("location")) { sl_reply_error(); } exit; } } # USER location service route[LOCATION] { if (!lookup("location")) { $var(rc) = $rc; t_newtran(); switch ($var(rc)) { case -1: case -3: send_reply("404", "Not Found"); exit; case -2: send_reply("405", "Method Not Allowed"); exit; } } route(RELAY); exit; } # Presence server route route[PRESENCE] { if (!is_method("PUBLISH|SUBSCRIBE")) { return; } if (is_method("SUBSCRIBE") && $hdr(Event) == "message-summary") { # returns here if no voicemail server is configured sl_send_reply("404", "No voicemail service"); exit; } #!ifdef WITH_PRESENCE if (!t_newtran()) { sl_reply_error(); exit; } if (is_method("PUBLISH")) { handle_publish(); t_release(); } else if (is_method("SUBSCRIBE")) { handle_subscribe(); t_release(); } exit; #!endif # if presence enabled, this part will not be executed if (is_method("PUBLISH") || $rU == $null) { sl_send_reply("404", "Not here"); exit; } return; } # Authentication route route[AUTH] { #!ifdef WITH_AUTH if (is_method("REGISTER") || from_uri == myself) { # authenticate requests if (!auth_check("$fd", "subscriber", "1")) { auth_challenge("$fd", "0"); exit; } # user authenticated - remove auth header if (!is_method("REGISTER|PUBLISH")) { consume_credentials(); } } # if caller is not local subscriber, then check if it calls # a local destination, otherwise deny, not an open relay here if (from_uri != myself && uri != myself) { sl_send_reply("403","Not relaying"); exit; } #!endif return; } # Caller NAT detection route route[NATDETECT] { #!ifdef WITH_IPV6 if(af==INET6) { return; } #!endif force_rport(); if (nat_uac_test("19")) { if (is_method("REGISTER")) { fix_nated_register(); } else if (is_first_hop()) { set_contact_alias(); } setflag(FLT_NATS); } return; } # NAT handling route[NATMANAGE] { if (is_request()) { if (has_totag()) { if (check_route_param("nat=yes")) { setbflag(FLB_NATB); } if (check_route_param("rtp=bridge")) { setbflag(FLB_BRIDGE); } if (check_route_param("rtp=ws")) { setbflag(FLB_RTPWS); } #!ifdef WITH_IPV6 if (check_route_param("rtp=v46")) { setbflag(FLB_V4V6); } #!endif } } if (!isbflagset(FLB_BRIDGE)) { return; } if ( !(isflagset(FLT_NATS) || isbflagset(FLB_NATB) || isbflagset(FLB_RTPWS) #!ifdef WITH_IPV6 || isbflagset(FLB_V4V6) #!endif ) ) { return; } $xavp(r=>$T_branch_idx) = "replace-origin replace-session-connection"; if (!nat_uac_test("8")) { $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " trust-address"; } if (is_request()) { if (!has_totag()) { if (!t_is_failure_route()) { $avp(extra_id) = @via[1].branch + $T_branch_idx; $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " via-branch=extra"; } } } if (is_reply()) { $avp(extra_id) = @via[2].branch + $T_branch_idx; $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " via-branch=extra"; } #!ifdef WITH_IPV6 if (af == INET && isbflagset(FLB_IPV6)) { # IPv4 --> IPv6 $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " address-family=IP6"; } else if (af == INET6 && !isbflagset(FLB_IPV6)) { # IPv6 --> IPv4 $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " address-family=IP4"; } #!endif if (isbflagset(FLB_RTPWS)) { if ($proto =~ "ws") { # web --> SIP $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " rtcp-mux-demux DTLS=off SDES-off ICE=remove RTP/AVP"; } else { # SIP --> web $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " rtcp-mux-offer generate-mid DTLS=passive SDES-off ICE=force RTP/SAVPF"; } } else { if ($proto =~ "ws") { # web --> web $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + " generate-mid DTLS=passive SDES-off ICE=force"; } # else { # $xavp(r=>$T_branch_idx) = $xavp(r=>$T_branch_idx) + ""; # } } xlog("L_INFO", "NATMANAGE branch_id:$T_branch_idx ruri: $ru, method:$rm, status:$rs, extra_id: $avp(extra_id), rtpengine_manage: $xavp(r=>$T_branch_idx)\n"); rtpengine_manage($xavp(r=>$T_branch_idx)); if (is_request()) { if (!has_totag()) { if (t_is_branch_route()) { if (isbflagset(FLB_NATB)) { add_rr_param(";nat=yes"); } if (isbflagset(FLB_BRIDGE)) { add_rr_param(";rtp=bridge"); } if (isbflagset(FLB_RTPWS)) { add_rr_param(";rtp=ws"); } #!ifdef WITH_IPV6 if (isbflagset(FLB_V4V6)) { add_rr_param(";rtp=v46"); } #!endif } } } if (is_reply()) { if (isbflagset(FLB_NATB)) { if (is_first_hop()) { if (af == INET) { set_contact_alias(); } } } } return; } # URI update for dialog requests route[DLGURI] { if (!isdsturiset()) { handle_ruri_alias(); } return; } # Routing to foreign domains route[SIPOUT] { if (!uri == myself) { append_hf("P-hint: outbound\r\n"); route(RELAY); } } route[BRIDGING] { if (!has_totag()) { if ($proto =~ "ws" && !($ru =~ "transport=ws")) { # Coming from WS, NOT to WS setbflag(FLB_RTPWS); # Need bridging } else if (!($proto =~ "ws") && $ru =~ "transport=ws") { # Coming from NOT WS, going to WS setbflag(FLB_RTPWS); # Need bridging } #!ifdef WITH_IPV6 if (af == INET6 && !isbflagset(FLB_IPV6)) { setbflag(FLB_V4V6); } else if(af == INET && isbflagset(FLB_IPV6)) { setbflag(FLB_V4V6); } #!endif } } # manage outgoing branches branch_route[MANAGE_BRANCH] { xlog("L_INFO", "MANAGE_BRANCH: New branch [$T_branch_idx] to $ru\n"); t_on_branch_failure("rtpengine"); #!ifndef WITH_BRIDGE_ON_FAIL setbflag(FLB_BRIDGE); #!endif route(BRIDGING); route(NATMANAGE); } # manage incoming replies onreply_route[MANAGE_REPLY] { xdbg("incoming reply\n"); if (status =~ "[12][0-9][0-9]") { route(NATMANAGE); } } # manage failure routing cases failure_route[MANAGE_FAILURE] { xlog("L_INFO", "Failure: $rs"); } #!ifdef WITH_WEBSOCKETS onreply_route { if ((($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS))) { xlog("L_WARN", "SIP response received on $Rp\n"); drop; } if (nat_uac_test(64)) { # Do NAT traversal stuff for replies to a WebSocket connection # - even if it is not behind a NAT! # This won't be needed in the future if Kamailio and the # WebSocket client support Outbound and Path. add_contact_alias(); } } event_route[tm:branch-failure:rtpengine] { xlog("L_INFO", "BRANCH FAILED: $sel(via[1].branch) + $T_branch_idx"); #!ifdef WITH_BRIDGE_ON_FAIL if (!isbflagset(FLB_BRIDGE) && t_check_status("415|488")) { t_reuse_branch(); setbflag(FLB_BRIDGE); xlog("L_INFO", "event_route[branch-failure:rtpengine]: trying again\n"); route(RELAY); } else { $avp(extra_id) = @via[1].branch + $T_branch_idx; rtpengine_delete("via-branch=extra"); xlog("L_INFO", "event_route[branch-failure:rtpengine]: failed\n"); } #!else $avp(extra_id) = @via[1].branch + $T_branch_idx; rtpengine_delete("via-branch=extra"); #!endif } event_route[xhttp:request] { set_reply_close(); set_reply_no_connect(); if ($Rp != MY_WS_PORT #!ifdef WITH_TLS && $Rp != MY_WSS_PORT #!endif ) { xlog("L_WARN", "HTTP request received on $Rp\n"); xhttp_reply("403", "Forbidden", "", ""); exit; } xlog("L_INFO", "HTTP Request Received\n"); if ($hdr(Upgrade) =~ "websocket" && $hdr(Connection) =~ "Upgrade" && $rm =~ "GET" ) { # Validate Host - make sure the client is using the correct # alias for WebSockets if ($hdr(Host) == $null || !is_myself("sip:" + $hdr(Host))) { xlog("L_WARN", "Bad host $hdr(Host)\n"); xhttp_reply("403", "Forbidden", "", ""); exit; } # Optional... validate Origin - make sure the client is from an # authorised website. For example, # # if ($hdr(Origin) != "https://example.com" # && $hdr(Origin) != "https://example.com") { # xlog("L_WARN", "Unauthorised client $hdr(Origin)\n"); # xhttp_reply("403", "Forbidden", "", ""); # exit; # } # Optional... perform HTTP authentication # ws_handle_handshake() exits (no further configuration file # processing of the request) when complete. if (ws_handle_handshake()) { # Optional... cache some information about the # successful connection exit; } } xhttp_reply("404", "Not Found", "", ""); } event_route[websocket:closed] { xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n"); } #!endif
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
-- Daniel-Constantin Mierla (@ asipto.com) twitter.com/miconda -- linkedin.com/in/miconda Kamailio Consultancy, Training and Development Services -- asipto.com Kamailio World Conference, April 18-19, 2024, Berlin -- kamailioworld.com