Browse Source

sctp rpc: core.sctp_options debugging version

core.sctp_options can now have 1 optional parameter. If the
parameter is missing it works as before: displays ser's idea of
all the sctp config options. If the parameter is present it should
have one of the following values: "default" (default send socket),
"first" (first sctp socket) or  addr[:port]. In this case the
kernel sctp options for that particular socket will be displayed,
with 0 used for the options that are userspace only.
E.g.:  sercmd core.sctp_options 127.0.0.1
Andrei Pelinescu-Onciul 16 years ago
parent
commit
44226358e6
1 changed files with 54 additions and 3 deletions
  1. 54 3
      core_cmd.c

+ 54 - 3
core_cmd.c

@@ -647,7 +647,13 @@ static void core_tcp_options(rpc_t* rpc, void* c)
 
 
 static const char* core_sctp_options_doc[] = {
-	"Returns active sctp options.",    /* Documentation string */
+	"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) */
 };
 
@@ -656,9 +662,54 @@ 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){
-		sctp_options_get(&t);
+		/* look for optional socket parameter */
+		if (rpc->scan(c, "*s", &param)>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,