diff --git a/CHANGELOG.md b/CHANGELOG.md index 69ee681e..8cb056be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Expected: February 2021 Developers may need to change their code +* rpc msg C API rearranged to separate socket/connect from connect * Added `cvv_i` output parameter to `api_path_fmt2api_path()` to see how many cvv entries were used. ### API changes on existing protocol/config features diff --git a/apps/backend/Makefile.in b/apps/backend/Makefile.in index a745c031..08aea10b 100644 --- a/apps/backend/Makefile.in +++ b/apps/backend/Makefile.in @@ -39,12 +39,12 @@ top_srcdir = @top_srcdir@ CC = @CC@ CFLAGS = @CFLAGS@ LINKAGE = @LINKAGE@ -ifeq ($(LINKAGE),dynamic) - CPPFLAGS = @CPPFLAGS@ -fPIC - SH_SUFFIX = @SH_SUFFIX@ -else +ifeq ($(LINKAGE),static) CPPFLAGS = @CPPFLAGS@ SH_SUFFIX = a +else + CPPFLAGS = @CPPFLAGS@ -fPIC + SH_SUFFIX = @SH_SUFFIX@ endif INSTALLFLAGS = @INSTALLFLAGS@ LDFLAGS = @LDFLAGS@ @@ -64,10 +64,10 @@ CLIXON_MAJOR = @CLIXON_VERSION_MAJOR@ CLIXON_MINOR = @CLIXON_VERSION_MINOR@ # Use this clixon lib for linking -ifeq ($(LINKAGE),dynamic) - CLIXON_LIB = libclixon$(SH_SUFFIX).$(CLIXON_MAJOR).$(CLIXON_MINOR) -else +ifeq ($(LINKAGE),static) CLIXON_LIB = libclixon.a +else + CLIXON_LIB = libclixon$(SH_SUFFIX).$(CLIXON_MAJOR).$(CLIXON_MINOR) endif # For dependency. A little strange that we rely on it being built in the src dir @@ -100,10 +100,10 @@ MYLIBSO = lib$(MYNAME)$(SH_SUFFIX).$(CLIXON_MAJOR) MYLIBLINK = lib$(MYNAME)$(SH_SUFFIX) MYLIBSTATIC = lib$(MYNAME).a -ifeq ($(LINKAGE),dynamic) - MYLIB = $(MYLIBDYNAMIC) -else +ifeq ($(LINKAGE),static) MYLIB = $(MYLIBSTATIC) +else + MYLIB = $(MYLIBDYNAMIC) endif all: $(MYLIB) $(APPL) test diff --git a/lib/clixon/clixon_proto.h b/lib/clixon/clixon_proto.h index 2d08a7ef..7ee87fed 100644 --- a/lib/clixon/clixon_proto.h +++ b/lib/clixon/clixon_proto.h @@ -75,16 +75,12 @@ int clicon_connect_unix(clicon_handle h, char *sockpath); int clicon_rpc_connect_unix(clicon_handle h, - struct clicon_msg *msg, char *sockpath, - char **ret, int *sock0); int clicon_rpc_connect_inet(clicon_handle h, - struct clicon_msg *msg, char *dst, uint16_t port, - char **ret, int *sock0); int clicon_rpc(int s, struct clicon_msg *msg, char **xret); diff --git a/lib/clixon/clixon_proto_client.h b/lib/clixon/clixon_proto_client.h index 9b3d277b..bb77bf0b 100644 --- a/lib/clixon/clixon_proto_client.h +++ b/lib/clixon/clixon_proto_client.h @@ -42,6 +42,7 @@ #ifndef _CLIXON_PROTO_CLIENT_H_ #define _CLIXON_PROTO_CLIENT_H_ +int clicon_rpc_connect(clicon_handle h, int *sock0); int clicon_rpc_msg(clicon_handle h, struct clicon_msg *msg, cxobj **xret0, int *sock0); int clicon_rpc_netconf(clicon_handle h, char *xmlst, cxobj **xret, int *sp); diff --git a/lib/src/Makefile.in b/lib/src/Makefile.in index c4a9520b..834aba13 100644 --- a/lib/src/Makefile.in +++ b/lib/src/Makefile.in @@ -53,10 +53,10 @@ CLIXON_MINOR = @CLIXON_VERSION_MINOR@ VPATH = @srcdir@ CC = @CC@ LINKAGE = @LINKAGE@ -ifeq ($(LINKAGE),dynamic) - CFLAGS = -fPIC @CFLAGS@ -else +ifeq ($(LINKAGE),static) CFLAGS = @CFLAGS@ +else + CFLAGS = -fPIC @CFLAGS@ endif SH_SUFFIX = @SH_SUFFIX@ INSTALL = @INSTALL@ @@ -107,10 +107,10 @@ MYLIBSO = lib$(MYNAME)$(SH_SUFFIX).$(CLIXON_MAJOR) MYLIBLINK = lib$(MYNAME)$(SH_SUFFIX) MYLIBSTATIC = lib$(MYNAME).a -ifeq ($(LINKAGE),dynamic) - MYLIB = $(MYLIBDYNAMIC) -else +ifeq ($(LINKAGE),static) MYLIB = $(MYLIBSTATIC) +else + MYLIB = $(MYLIBDYNAMIC) endif all: $(MYLIB) $(MYLIBLINK) diff --git a/lib/src/clixon_log.c b/lib/src/clixon_log.c index 793ac5d7..f3858099 100644 --- a/lib/src/clixon_log.c +++ b/lib/src/clixon_log.c @@ -315,6 +315,7 @@ clicon_debug_init(int dbglevel, FILE *f) { _clixon_debug = dbglevel; /* Global variable */ + _logfile = f; return 0; } diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 379e227c..6f4df311 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -562,16 +562,18 @@ clicon_msg_rcv(int s, */ int clicon_rpc_connect_unix(clicon_handle h, - struct clicon_msg *msg, char *sockpath, - char **retdata, int *sock0) { - int retval = -1; - int s = -1; - struct stat sb; + int retval = -1; + int s = -1; + struct stat sb = {0,}; clicon_debug(1, "Send msg on %s", sockpath); + if (sock0 == NULL){ + clicon_err(OE_NETCONF, EINVAL, "sock0 expected"); + goto done; + } /* special error handling to get understandable messages (otherwise ENOENT) */ if (stat(sockpath, &sb) < 0){ clicon_err(OE_PROTO, errno, "%s: config daemon not running?", sockpath); @@ -583,14 +585,9 @@ clicon_rpc_connect_unix(clicon_handle h, } if ((s = clicon_connect_unix(h, sockpath)) < 0) goto done; - if (clicon_rpc(s, msg, retdata) < 0) - goto done; - if (sock0 != NULL) - *sock0 = s; + *sock0 = s; retval = 0; done: - if (sock0 == NULL && s >= 0) - close(s); return retval; } @@ -608,10 +605,8 @@ clicon_rpc_connect_unix(clicon_handle h, */ int clicon_rpc_connect_inet(clicon_handle h, - struct clicon_msg *msg, char *dst, uint16_t port, - char **retdata, int *sock0) { int retval = -1; @@ -619,7 +614,10 @@ clicon_rpc_connect_inet(clicon_handle h, struct sockaddr_in addr; clicon_debug(1, "Send msg to %s:%hu", dst, port); - + if (sock0 == NULL){ + clicon_err(OE_NETCONF, EINVAL, "sock0 expected"); + goto done; + } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); @@ -636,14 +634,9 @@ clicon_rpc_connect_inet(clicon_handle h, close(s); goto done; } - if (clicon_rpc(s, msg, retdata) < 0) - goto done; - if (sock0 != NULL) - *sock0 = s; + *sock0 = s; retval = 0; done: - if (sock0 == NULL && s >= 0) - close(s); return retval; } diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 35d3bf5c..04487288 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -82,31 +82,16 @@ #include "clixon_netconf_lib.h" #include "clixon_proto_client.h" -/*! Send internal netconf rpc from client to backend - * @param[in] h CLICON handle - * @param[in] msg Encoded message. Deallocate with free - * @param[out] xret0 Return value from backend as xml tree. Free w xml_free - * @param[inout] sock0 If pointer exists, do not close socket to backend on success - * and return it here. For keeping a notify socket open - * @note sock0 is if connection should be persistent, like a notification/subscribe api - * @note xret is populated with yangspec according to standard handle yangspec +/*! Connect to internal netconf socket */ int -clicon_rpc_msg(clicon_handle h, - struct clicon_msg *msg, - cxobj **xret0, - int *sock0) +clicon_rpc_connect(clicon_handle h, + int *sock0) { - int retval = -1; - char *sock; - int port; - char *retdata = NULL; - cxobj *xret = NULL; + int retval = -1; + char *sock = NULL; + int port; -#ifdef RPC_USERNAME_ASSERT - assert(strstr(msg->op_body, "username")!=NULL); /* XXX */ -#endif - clicon_debug(1, "%s request:%s", __FUNCTION__, msg->op_body); if ((sock = clicon_sock(h)) == NULL){ clicon_err(OE_FATAL, 0, "CLICON_SOCK option not set"); goto done; @@ -114,7 +99,7 @@ clicon_rpc_msg(clicon_handle h, /* What to do if inet socket? */ switch (clicon_sock_family(h)){ case AF_UNIX: - if (clicon_rpc_connect_unix(h, msg, sock, &retdata, sock0) < 0){ + if (clicon_rpc_connect_unix(h, sock, sock0) < 0){ #if 0 if (errno == ESHUTDOWN) /* Maybe could reconnect on a higher layer, but lets fail @@ -133,10 +118,45 @@ clicon_rpc_msg(clicon_handle h, clicon_err(OE_FATAL, 0, "CLICON_SOCK_PORT not set"); goto done; } - if (clicon_rpc_connect_inet(h, msg, sock, port, &retdata, sock0) < 0) + if (clicon_rpc_connect_inet(h, sock, port, sock0) < 0) goto done; break; } + retval = 0; + done: + return retval; +} + +/*! Send internal netconf rpc from client to backend + * @param[in] h CLICON handle + * @param[in] msg Encoded message. Deallocate with free + * @param[out] xret0 Return value from backend as xml tree. Free w xml_free + * @param[inout] sock0 If pointer exists, do not close socket to backend on success + * and return it here. For keeping a notify socket open + * @note sock0 is if connection should be persistent, like a notification/subscribe api + * @note xret is populated with yangspec according to standard handle yangspec + */ +int +clicon_rpc_msg(clicon_handle h, + struct clicon_msg *msg, + cxobj **xret0, + int *sock0) +{ + int retval = -1; + char *retdata = NULL; + cxobj *xret = NULL; + int s = -1; + +#ifdef RPC_USERNAME_ASSERT + assert(strstr(msg->op_body, "username")!=NULL); /* XXX */ +#endif + clicon_debug(1, "%s request:%s", __FUNCTION__, msg->op_body); + /* Create a socket and connect to it, either UNIX, IPv4 or IPv6 per config options */ + if (clicon_rpc_connect(h, &s) < 0) + goto done; + if (clicon_rpc(s, msg, &retdata) < 0) + goto done; + clicon_debug(1, "%s retdata:%s", __FUNCTION__, retdata); if (retdata){ @@ -150,8 +170,15 @@ clicon_rpc_msg(clicon_handle h, *xret0 = xret; xret = NULL; } + /* If returned, keep socket open, otherwise close it below */ + if (sock0){ + *sock0 = s; + s = -1; + } retval = 0; done: + if (s != -1) + close(s); if (retdata) free(retdata); if (xret) diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index 6e7262c8..c8fdcc27 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -706,7 +706,7 @@ xpath_first_localonly(cxobj *xcur, * @retval -1 Error * @code * cvec *nsc; // namespace context - * cxobj **vec; + * cxobj **vec = NULL; * size_t veclen; * if (xpath_vec(xcur, nsc, "//symbol/foo", &vec, &veclen) < 0) * err; diff --git a/util/Makefile.in b/util/Makefile.in index 49901516..1e69cd2a 100644 --- a/util/Makefile.in +++ b/util/Makefile.in @@ -63,13 +63,14 @@ INSTALLFLAGS = @INSTALLFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ CPPFLAGS = @CPPFLAGS@ +LINKAGE = @LINKAGE@ INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib -I$(top_srcdir)/include -ifeq ($(LINKAGE),dynamic) - CLIXON_LIB = libclixon$(SH_SUFFIX).$(CLIXON_MAJOR).$(CLIXON_MINOR) -else +ifeq ($(LINKAGE),static) CLIXON_LIB = libclixon.a +else + CLIXON_LIB = libclixon$(SH_SUFFIX).$(CLIXON_MAJOR).$(CLIXON_MINOR) endif # For dependency. A little strange that we rely on it being built in the src dir diff --git a/util/clixon_util_socket.c b/util/clixon_util_socket.c index 4fa3aa3d..5c886def 100644 --- a/util/clixon_util_socket.c +++ b/util/clixon_util_socket.c @@ -96,6 +96,7 @@ main(int argc, cbuf *cb = cbuf_new(); clicon_handle h; int dbg = 0; + int s; /* In the startup, logs to stderr & debug flag set later */ clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR); @@ -167,12 +168,15 @@ main(int argc, if ((msg = clicon_msg_encode(getpid(), "%s", cbuf_get(cb))) < 0) goto done; if (strcmp(family, "UNIX")==0){ - if (clicon_rpc_connect_unix(h, msg, sockpath, &retdata, NULL) < 0) + if (clicon_rpc_connect_unix(h, sockpath, &s) < 0) goto done; } else - if (clicon_rpc_connect_inet(h, msg, sockpath, 4535, &retdata, NULL) < 0) + if (clicon_rpc_connect_inet(h, sockpath, 4535, &s) < 0) goto done; + if (clicon_rpc(s, msg, &retdata) < 0) + goto done; + close(s); fprintf(stdout, "%s\n", retdata); retval = 0; done: