diff options
| author | /C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org> | 2007-05-18 19:33:40 +0000 | 
|---|---|---|
| committer | /C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org> | 2007-05-18 19:33:40 +0000 | 
| commit | 2932c6b8e6952ae84b221b854b43810c61e5c8fa (patch) | |
| tree | 1ee7f364f74f2dff2b462ab01868a74fd87f1403 /src | |
| parent | 34d1c62cd414a6d3321d9a51fc6e1d61f36da2f0 (diff) | |
| download | conntrack-tools-2932c6b8e6952ae84b221b854b43810c61e5c8fa.tar.gz conntrack-tools-2932c6b8e6952ae84b221b854b43810c61e5c8fa.zip  | |
- remove dead code sync-mode.c
- flush nack queue in the conntrackd -f path
- do not increase add_fail counter for EEXIST errors
- cleanup sync-nack code
- improve mcast_recv_netmsg: sanity check before checksumming!
Diffstat (limited to 'src')
| -rw-r--r-- | src/cache.c | 9 | ||||
| -rw-r--r-- | src/cache_iterators.c | 6 | ||||
| -rw-r--r-- | src/network.c | 47 | ||||
| -rw-r--r-- | src/sync-mode.c | 51 | ||||
| -rw-r--r-- | src/sync-nack.c | 71 | ||||
| -rw-r--r-- | src/sync-notrack.c | 4 | 
6 files changed, 93 insertions, 95 deletions
diff --git a/src/cache.c b/src/cache.c index 6f7442b..32caee5 100644 --- a/src/cache.c +++ b/src/cache.c @@ -228,7 +228,7 @@ static struct us_conntrack *__add(struct cache *c, struct nf_conntrack *ct)  			data += c->features[i]->size;  		} -		if (c->extra) +		if (c->extra && c->extra->add)  			c->extra->add(u, ((void *) u) + c->extra_offset);  		return u; @@ -247,7 +247,8 @@ struct us_conntrack *__cache_add(struct cache *c, struct nf_conntrack *ct)  		c->add_ok++;  		return u;  	} -	c->add_fail++; +	if (errno != EEXIST) +		c->add_fail++;  	return NULL;  } @@ -281,7 +282,7 @@ static struct us_conntrack *__update(struct cache *c, struct nf_conntrack *ct)  			data += c->features[i]->size;  		} -		if (c->extra) +		if (c->extra && c->extra->update)  			c->extra->update(u, ((void *) u) + c->extra_offset);  		if (nfct_attr_is_set(ct, ATTR_STATUS)) @@ -380,7 +381,7 @@ static int __del(struct cache *c, struct nf_conntrack *ct)  			data += c->features[i]->size;  		} -		if (c->extra) +		if (c->extra && c->extra->destroy)  			c->extra->destroy(u, ((void *) u) + c->extra_offset);  		hashtable_del(c->h, u); diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 5d5d22b..e1f3798 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -182,6 +182,10 @@ static int do_flush(void *data1, void *data2)  		c->features[i]->destroy(u, data);  		data += c->features[i]->size;  	} + +	if (c->extra && c->extra->destroy) +		c->extra->destroy(u, ((void *) u) + c->extra_offset); +  	free(u->ct);  	return 0; @@ -215,7 +219,7 @@ static int do_bulk(void *data1, void *data2)  		debug_ct(u->ct, "failed to build");  	mcast_send_netmsg(STATE_SYNC(mcast_client), net); -	STATE_SYNC(mcast_sync)->post_send(net, u); +	STATE_SYNC(mcast_sync)->post_send(NFCT_T_UPDATE, net, u);  	/* keep iterating even if we have found errors */  	return 0; diff --git a/src/network.c b/src/network.c index b9be318..51e89c7 100644 --- a/src/network.c +++ b/src/network.c @@ -70,7 +70,7 @@ int mcast_resend_netmsg(struct mcast_sock *m, void *data)  {  	struct nlnetwork *net = data;  	struct nlmsghdr *nlh = data + sizeof(struct nlnetwork); -	unsigned int len = htonl(nlh->nlmsg_len) + sizeof(struct nlnetwork); +	unsigned int len;  	net->flags = ntohs(net->flags); @@ -80,10 +80,10 @@ int mcast_resend_netmsg(struct mcast_sock *m, void *data)  		net->flags |= NET_HELLO;  	} -	if (net->flags & NET_NACK || net->flags & NET_ACK) { -		struct nlnetwork_ack *nack = (struct nlnetwork_ack *) net; +	if (net->flags & NET_NACK || net->flags & NET_ACK)  		len = sizeof(struct nlnetwork_ack); -	} +	else +		len = sizeof(struct nlnetwork) + ntohl(nlh->nlmsg_len);  	net->flags = htons(net->flags);  	net->seq = htonl(cur_seq++); @@ -147,32 +147,44 @@ int mcast_recv_netmsg(struct mcast_sock *m, void *data, int len)  	if (ret <= 0)  		return ret; +	/* message too small: no room for the header */  	if (ret < sizeof(struct nlnetwork))  		return -1; -	if (!valid_checksum(data, ret)) -		return -1; - -	net->flags = ntohs(net->flags); -	net->seq = ntohl(net->seq); - -	if (net->flags & NET_HELLO) -		STATE_SYNC(last_seq_recv) = net->seq-1; +	if (ntohs(net->flags) & NET_HELLO) +		STATE_SYNC(last_seq_recv) = ntohl(net->seq) - 1; -	if (net->flags & NET_NACK || net->flags & NET_ACK) { +	if (ntohs(net->flags) & NET_NACK || ntohs(net->flags) & NET_ACK) {  		struct nlnetwork_ack *nack = (struct nlnetwork_ack *) net; +		/* message too small: no room for the header */  		if (ret < sizeof(struct nlnetwork_ack))  			return -1; +		if (!valid_checksum(data, ret)) +			return -1; + +		/* host byte order conversion */ +		net->flags = ntohs(net->flags); +		net->seq = ntohl(net->seq); + +		/* acknowledgement conversion */  		nack->from = ntohl(nack->from);  		nack->to = ntohl(nack->to);  		return ret;  	} -	if (net->flags & NET_RESYNC) +	if (ntohs(net->flags) & NET_RESYNC) { +		if (!valid_checksum(data, ret)) +			return -1; + +		/* host byte order conversion */ +		net->flags = ntohs(net->flags); +		net->seq = ntohl(net->seq); +  		return ret; +	}  	/* information received is too small */  	if (ret < NLMSG_SPACE(sizeof(struct nfgenmsg))) @@ -197,6 +209,13 @@ int mcast_recv_netmsg(struct mcast_sock *m, void *data, int len)  	if (nfhdr->version != NFNETLINK_V0)  		return -1; +	if (!valid_checksum(data, ret)) +		return -1; + +	/* host byte order conversion */ +	net->flags = ntohs(net->flags); +	net->seq = ntohl(net->seq); +  	if (nlh_network2host(nlh) == -1)  		return -1; diff --git a/src/sync-mode.c b/src/sync-mode.c index b32bef7..0a195d7 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -282,18 +282,15 @@ static void mcast_send_sync(struct nlmsghdr *nlh,  {  	char buf[4096];  	struct nlnetwork *net = (struct nlnetwork *) buf; -	int mangled = 0;  	memset(buf, 0, sizeof(buf));  	if (!state_helper_verdict(type, ct))  		return; -	if (!mangled) -		memcpy(buf + sizeof(struct nlnetwork), nlh, nlh->nlmsg_len); - +	memcpy(buf + sizeof(struct nlnetwork), nlh, nlh->nlmsg_len);  	mcast_send_netmsg(STATE_SYNC(mcast_client), net);  -	STATE_SYNC(mcast_sync)->post_send(net, u); +	STATE_SYNC(mcast_sync)->post_send(type, net, u);  }  static void overrun_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh) @@ -333,7 +330,8 @@ retry:  	} else {  		if (errno == EEXIST) {  			char buf[4096]; -			struct nlmsghdr *nlh = (struct nlmsghdr *) buf; +			unsigned int size = sizeof(struct nlnetwork); +			struct nlmsghdr *nlh = (struct nlmsghdr *) (buf + size);  			int ret = build_network_msg(NFCT_Q_DESTROY,  						    STATE(subsys_event), @@ -344,9 +342,10 @@ retry:  				return;  			cache_del(STATE_SYNC(internal), ct); -			mcast_send_sync(nlh, NULL, ct, NFCT_T_NEW); +			mcast_send_sync(nlh, NULL, ct, NFCT_T_DESTROY);  			goto retry;  		} +  		dlog(STATE(log), "can't add to internal cache: "  				      "%s\n", strerror(errno));  		debug_ct(ct, "can't add"); @@ -360,19 +359,8 @@ static void event_update_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh)  	nfct_attr_unset(ct, ATTR_TIMEOUT);  	if ((u = cache_update(STATE_SYNC(internal), ct)) == NULL) { -		/* -		 * Perhaps we are losing events. If we are working  -		 * in relax mode then add a new entry to the cache. -		 * -		 * FIXME: relax transitions not implemented yet -		 */ -		if ((CONFIG(flags) & RELAX_TRANSITIONS) -		    && (u = cache_add(STATE_SYNC(internal), ct))) { -			debug_ct(u->ct, "forcing internal update"); -		} else { -			debug_ct(ct, "can't update"); -			return; -		} +		debug_ct(ct, "can't update"); +		return;  	}  	debug_ct(u->ct, "internal update");  	mcast_send_sync(nlh, u, ct, NFCT_T_UPDATE); @@ -382,24 +370,11 @@ static int event_destroy_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh)  {  	nfct_attr_unset(ct, ATTR_TIMEOUT); -	if (CONFIG(flags) & DELAY_DESTROY_MSG) { - -		nfct_set_attr_u32(ct, ATTR_STATUS, IPS_DYING); - -		if (cache_update(STATE_SYNC(internal), ct)) { -			debug_ct(ct, "delay internal destroy"); -			return 1; -		} else { -			debug_ct(ct, "can't delay destroy!"); -			return 0; -		} -	} else { -		if (cache_del(STATE_SYNC(internal), ct)) { -			mcast_send_sync(nlh, NULL, ct, NFCT_T_DESTROY); -			debug_ct(ct, "internal destroy"); -		} else -			debug_ct(ct, "can't destroy"); -	} +	if (cache_del(STATE_SYNC(internal), ct)) { +		mcast_send_sync(nlh, NULL, ct, NFCT_T_DESTROY); +		debug_ct(ct, "internal destroy"); +	} else +		debug_ct(ct, "can't destroy");  }  struct ct_mode sync_mode = { diff --git a/src/sync-nack.c b/src/sync-nack.c index 288dba4..73f6dc2 100644 --- a/src/sync-nack.c +++ b/src/sync-nack.c @@ -43,37 +43,24 @@ struct cache_nack {  static void cache_nack_add(struct us_conntrack *u, void *data)  {  	struct cache_nack *cn = data; -  	INIT_LIST_HEAD(&cn->head); -	list_add(&cn->head, &queue);  } -static void cache_nack_update(struct us_conntrack *u, void *data) +static void cache_nack_del(struct us_conntrack *u, void *data)  {  	struct cache_nack *cn = data; -	if (cn->head.next != LIST_POISON1 && -	    cn->head.prev != LIST_POISON2) -		list_del(&cn->head); +	if (cn->head.next == &cn->head && +	    cn->head.prev == &cn->head) +	    	return; -	INIT_LIST_HEAD(&cn->head); -	list_add(&cn->head, &queue); -} - -static void cache_nack_destroy(struct us_conntrack *u, void *data) -{ -	struct cache_nack *cn = data; - -	if (cn->head.next != LIST_POISON1 && -	    cn->head.prev != LIST_POISON2) -		list_del(&cn->head); +	list_del(&cn->head);  }  static struct cache_extra cache_nack_extra = {  	.size 		= sizeof(struct cache_nack),  	.add		= cache_nack_add, -	.update		= cache_nack_update, -	.destroy	= cache_nack_destroy +	.destroy	= cache_nack_del  };  static int nack_init() @@ -200,7 +187,9 @@ static void queue_resend(struct cache *c, unsigned int from, unsigned int to)  			}  			mcast_send_netmsg(STATE_SYNC(mcast_client), buf);  -			STATE_SYNC(mcast_sync)->post_send(net, u); +			STATE_SYNC(mcast_sync)->post_send(NFCT_T_UPDATE, +							  net,  +							  u);  			dp("(newseq=%u)\n", *seq);  		}   	} @@ -224,6 +213,7 @@ static void queue_empty(struct cache *c, unsigned int from, unsigned int to)  			debug_ct(u->ct, "ack received: empty queue");  			dp("queue: deleting from queue (seq=%u)\n", cn->seq);  			list_del(&cn->head); +			INIT_LIST_HEAD(&cn->head);  		}   	}  	unlock(); @@ -272,28 +262,35 @@ static int nack_pre_recv(const struct nlnetwork *net)  	return 0;  } -static void nack_post_send(const struct nlnetwork *net, struct us_conntrack *u) +static void nack_post_send(int type,  +			   const struct nlnetwork *net,  +			   struct us_conntrack *u)  { -	unsigned int size = sizeof(struct nlnetwork); -	struct nlmsghdr *nlh = (struct nlmsghdr *) ((void *) net + size); - -	if (NFNL_MSG_TYPE(ntohs(nlh->nlmsg_type)) == IPCTNL_MSG_CT_DELETE) { -		buffer_add(STATE_SYNC(buffer), net,  -			   ntohl(nlh->nlmsg_len) + size);  -	} else if (u != NULL) { -		unsigned int *seq; -		struct list_head *n; -		struct cache_nack *cn; - -		cn = (struct cache_nack *) +	unsigned int size = sizeof(struct nlnetwork);  + 	struct nlmsghdr *nlh = (struct nlmsghdr *) ((void *) net + size); +	struct cache_nack *cn; +  +	size += ntohl(nlh->nlmsg_len); + +	switch(type) { +	case NFCT_T_NEW: +	case NFCT_T_UPDATE: +		cn = (struct cache_nack *)   			cache_get_extra(STATE_SYNC(internal), u); -		cn->seq = ntohl(net->seq); -		if (cn->head.next != LIST_POISON1 && -		    cn->head.prev != LIST_POISON2) -		    	list_del(&cn->head); +		if (cn->head.next == &cn->head && +		    cn->head.prev == &cn->head) +		    	goto insert; + +		list_del(&cn->head);  		INIT_LIST_HEAD(&cn->head); +insert: +		cn->seq = ntohl(net->seq);  		list_add(&cn->head, &queue); +		break; +	case NFCT_T_DESTROY: +		buffer_add(STATE_SYNC(buffer), net, size); +		break;  	}  } diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 2b5ae38..cc56436 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -114,7 +114,9 @@ static int notrack_pre_recv(const struct nlnetwork *net)  	return 0;  } -static void notrack_post_send(const struct nlnetwork *n, struct us_conntrack *u) +static void notrack_post_send(int type, +			      const struct nlnetwork *n,  +			      struct us_conntrack *u)  {  }  | 
