/* * $Id$ * * Copyright (C) 2009 iptelorg GmbH * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "../../rpc_lookup.h" #include "../../socket_info.h" #include "../../globals.h" #include "../../config.h" #ifdef USE_SCTP #include "sctp_options.h" #include "sctp_server.h" #endif static const char* core_sctp_options_doc[] = { "Returns active sctp options. With one parameter" " it returns the sctp options set in the kernel for a specific socket" "(debugging), with 0 filled in for non-kernel related options." " The parameter can be: \"default\" | \"first\" | address[:port] ." " With no parameters it returns ser's idea of the current sctp options" " (intended non-debugging use).", /* Documentation string */ 0 /* Method signature(s) */ }; static void core_sctp_options(rpc_t* rpc, void* c) { #ifdef USE_SCTP void *handle; struct cfg_group_sctp t; char* param; struct socket_info* si; char* host; str hs; int hlen; int port; int proto; param=0; if (!sctp_disable){ /* look for optional socket parameter */ if (rpc->scan(c, "*s", ¶m)>0){ si=0; if (strcasecmp(param, "default")==0){ si=sendipv4_sctp?sendipv4_sctp:sendipv6_sctp; }else if (strcasecmp(param, "first")==0){ si=sctp_listen; }else{ if (parse_phostport(param, &host, &hlen, &port, &proto)!=0){ rpc->fault(c, 500, "bad param (use address, address:port," " default or first)"); return; } if (proto && proto!=PROTO_SCTP){ rpc->fault(c, 500, "bad protocol in param (only SCTP" " allowed)"); return; } hs.s=host; hs.len=hlen; si=grep_sock_info(&hs, port, PROTO_SCTP); if (si==0){ rpc->fault(c, 500, "not listening on sctp %s", param); return; } } if (si==0 || si->socket==-1){ rpc->fault(c, 500, "could not find a sctp socket"); return; } memset(&t, 0, sizeof(t)); if (sctp_get_cfg_from_sock(si->socket, &t)!=0){ rpc->fault(c, 500, "failed to get socket options"); return; } }else{ sctp_options_get(&t); } rpc->add(c, "{", &handle); rpc->struct_add(handle, "ddddddddddddddddddd", "sctp_socket_rcvbuf", t.so_rcvbuf, "sctp_socket_sndbuf", t.so_sndbuf, "sctp_autoclose", t.autoclose, "sctp_send_ttl", t.send_ttl, "sctp_send_retries", t.send_retries, "sctp_assoc_tracking", t.assoc_tracking, "sctp_assoc_reuse", t.assoc_reuse, "sctp_max_assocs", t.max_assocs, "sctp_srto_initial", t.srto_initial, "sctp_srto_max", t.srto_max, "sctp_srto_min", t.srto_min, "sctp_asocmaxrxt", t.asocmaxrxt, "sctp_init_max_attempts", t.init_max_attempts, "sctp_init_max_timeo",t.init_max_timeo, "sctp_hbinterval", t.hbinterval, "sctp_pathmaxrxt", t.pathmaxrxt, "sctp_sack_delay", t.sack_delay, "sctp_sack_freq", t.sack_freq, "sctp_max_burst", t.max_burst ); }else{ rpc->fault(c, 500, "sctp support disabled"); } #else rpc->fault(c, 500, "sctp support not compiled"); #endif } static const char* core_sctpinfo_doc[] = { "Returns sctp related info.", /* Documentation string */ 0 /* Method signature(s) */ }; static void core_sctpinfo(rpc_t* rpc, void* c) { #ifdef USE_SCTP void *handle; struct sctp_gen_info i; if (!sctp_disable){ sctp_get_info(&i); rpc->add(c, "{", &handle); rpc->struct_add(handle, "ddd", "opened_connections", i.sctp_connections_no, "tracked_connections", i.sctp_tracked_no, "total_connections", i.sctp_total_connections ); }else{ rpc->fault(c, 500, "sctp support disabled"); } #else rpc->fault(c, 500, "sctp support not compiled"); #endif } /* * RPC Methods exported by this module */ static rpc_export_t sctp_rpc_methods[] = { {"sctp.options", core_sctp_options, core_sctp_options_doc, 0}, {"sctp.info", core_sctpinfo, core_sctpinfo_doc, 0}, {0, 0, 0, 0} }; int sctp_register_rpc(void) { if (rpc_register_array(sctp_rpc_methods)!=0) { LM_ERR("failed to register RPC commands\n"); return -1; } return 0; }