All of lore.kernel.org
 help / color / mirror / Atom feed
From: Derrik Pates <demon@devrandom.net>
To: netfilter-devel@lists.netfilter.org
Subject: Patch to libiptc
Date: Sat, 22 Jan 2005 19:28:49 -0500	[thread overview]
Message-ID: <41F2EFC1.2050904@devrandom.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 1197 bytes --]

All:

The attached patch fixes a few minor issues in libiptc. These changes 
are as follows:

   - Sets the 'iptc_fn' global variable to the pointer to the current 
functions in all major TC_* functions. This is necessary because in 
certain cases, an error return from a function that doesn't set 
'iptc_fn' will conflict with a function-specific error return from one 
that does, causing TC_STRERROR() to return the wrong error string. This 
ensures that the right one will be returned.
   - Implements a simple reference counter for the netlink socket global 
variable 'sockfd'; this is necessary for IPTables::IPv4, where multiple 
tables (filter, nat, mangle, untracked) may be opened at one time. The 
way libiptc does it in the official version causes previously-opened 
tables to break such that attempts to commit changes will fail.
   - Adds a couple of memset() invocations in TC_COMMIT, based on past 
analysis with valgrind. It claimed that allocated structure were not 
being fully initialized, and adding the memset()s corrected this warning.

It is against the current version in the Subversion repository. It only 
changes libiptc/libiptc.c.

-- 
Derrik Pates
demon@devrandom.net

[-- Attachment #2: libiptc-fixes.diff --]
[-- Type: text/x-patch, Size: 3437 bytes --]

--- iptables/libiptc/libiptc.c.stock	2005-01-22 12:45:11.981755400 -0500
+++ iptables/libiptc/libiptc.c	2005-01-22 17:01:08.257590648 -0500
@@ -45,6 +45,7 @@
 #endif
 
 static int sockfd = -1;
+static int sockfd_use = 0;
 static void *iptc_fn = NULL;
 
 static const char *hooknames[]
@@ -788,33 +789,38 @@
 
 	iptc_fn = TC_INIT;
 
-	if (sockfd != -1) {
-		close(sockfd);
-		sockfd = -1;
-	}
-
 	if (strlen(tablename) >= TABLE_MAXNAMELEN) {
 		errno = EINVAL;
 		return NULL;
 	}
 	
-	sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
-	if (sockfd < 0)
-		return NULL;
+	if (sockfd_use == 0) {
+		sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
+		if (sockfd < 0)
+			return NULL;
+	}
+	sockfd_use++;
 
 	s = sizeof(info);
 
 	strcpy(info.name, tablename);
-	if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0)
+	if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) {
+		if (--sockfd_use == 0) {
+			close(sockfd);
+			sockfd = -1;
+		}
 		return NULL;
+	}
 
 	DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n",
 		info.valid_hooks, info.num_entries, info.size);
 
 	if ((h = alloc_handle(info.name, info.size, info.num_entries))
 	    == NULL) {
-		close(sockfd);
-		sockfd = -1;
+		if (--sockfd_use == 0) {
+			close(sockfd);
+			sockfd = -1;
+		}
 		return NULL;
 	}
 
@@ -846,6 +852,10 @@
 	CHECK(h);
 	return h;
 error:
+	if (--sockfd_use == 0) {
+		close(sockfd);
+		sockfd = -1;
+	}
 	TC_FREE(&h);
 	return NULL;
 }
@@ -855,8 +865,11 @@
 {
 	struct chain_head *c, *tmp;
 
-	close(sockfd);
-	sockfd = -1;
+	iptc_fn = TC_FREE;
+	if (--sockfd_use == 0) {
+		close(sockfd);
+		sockfd = -1;
+	}
 
 	list_for_each_entry_safe(c, tmp, &(*h)->chains, list) {
 		struct rule_head *r, *rtmp;
@@ -886,6 +899,7 @@
 void
 TC_DUMP_ENTRIES(const TC_HANDLE_T handle)
 {
+	iptc_fn = TC_DUMP_ENTRIES;
 	CHECK(handle);
 #if 0
 	printf("libiptc v%s. %u bytes.\n",
@@ -912,6 +926,7 @@
 /* Does this chain exist? */
 int TC_IS_CHAIN(const char *chain, const TC_HANDLE_T handle)
 {
+	iptc_fn = TC_IS_CHAIN;
 	return iptcc_find_label(chain, handle) != NULL;
 }
 
@@ -1003,6 +1018,7 @@
 {
 	struct rule_head *r;
 
+	iptc_fn = TC_NEXT_RULE;
 	DEBUGP("rule_iterator_cur=%p...", (*handle)->rule_iterator_cur);
 
 	if (!(*handle)->rule_iterator_cur) {
@@ -1576,6 +1592,7 @@
 		STRUCT_ENTRY *entry,
 		TC_HANDLE_T *handle)
 {
+	iptc_fn = TC_CHECK_PACKET;
 	errno = ENOSYS;
 	return NULL;
 }
@@ -1611,6 +1628,7 @@
 	struct chain_head *c;
 	struct rule_head *r;
 
+	iptc_fn = TC_ZERO_ENTRIES;
 	if (!(c = iptcc_find_label(chain, *handle))) {
 		errno = ENOENT;
 		return 0;
@@ -1763,6 +1781,7 @@
 {
 	struct chain_head *c;
 
+	iptc_fn = TC_GET_REFERENCES;
 	if (!(c = iptcc_find_label(chain, *handle))) {
 		errno = ENOENT;
 		return 0;
@@ -1991,6 +2010,7 @@
 	int new_number;
 	unsigned int new_size;
 
+	iptc_fn = TC_COMMIT;
 	CHECK(*handle);
 
 	/* Don't commit if nothing changed. */
@@ -2016,6 +2036,7 @@
 
 	counterlen = sizeof(STRUCT_COUNTERS_INFO)
 			+ sizeof(STRUCT_COUNTERS) * new_number;
+	memset(repl, 0, sizeof(*repl) + (*handle)->entries->size);
 
 	/* These are the old counters we will get from kernel */
 	repl->counters = malloc(sizeof(STRUCT_COUNTERS)
@@ -2025,6 +2046,8 @@
 		errno = ENOMEM;
 		return 0;
 	}
+	memset(repl->counters, 0, sizeof(STRUCT_COUNTERS)
+			* (*handle)->info.num_entries);
 	/* These are the counters we're going to put back, later. */
 	newcounters = malloc(counterlen);
 	if (!newcounters) {

             reply	other threads:[~2005-01-23  0:28 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-23  0:28 Derrik Pates [this message]
2005-02-01 13:25 ` Patch to libiptc Harald Welte

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=41F2EFC1.2050904@devrandom.net \
    --to=demon@devrandom.net \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.