[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
ipropd-master CLOSE_WAIT problem
Hi all!
On linux (I didn't tested other platforms) ipropd-master doesn't handle
tcp sockets well.
If an perviously connected replica disconnect from ipropd-master, then
ipropd-master will not close the used tcp socket until the replica
reconnect again.
Because it the the tcp socket will be in CLOSE_WAIT state.
Because it the select func in every loop will report this socket
as activ and will never sleep, so ipropd-master will eat all the
CPU time until the replica reconnect.
The following patch correct the above problem for me on linux
platform. As I wrote I didn't tested it on other platforms and it can be
buggy, so it is only for demonstration purposes.
If possible correct the mainstream code.
Thanks.
balsa
diff -Naur heimdal-0.5.1-orig/lib/kadm5/ipropd_master.c heimdal-0.5.1/lib/kadm5/ipropd_master.c
--- heimdal-0.5.1-orig/lib/kadm5/ipropd_master.c 2002-08-16 20:27:53.000000000 +0200
+++ heimdal-0.5.1/lib/kadm5/ipropd_master.c 2003-03-13 03:19:21.000000000 +0100
@@ -87,6 +87,7 @@
time_t seen;
unsigned long flags;
#define SLAVE_F_DEAD 0x1
+#define SLAVE_FD_CLOSED 0x2
struct slave *next;
};
@@ -132,7 +133,7 @@
{
slave **p;
- if (s->fd >= 0)
+ if (!(s->flags & SLAVE_FD_CLOSED) && s->fd >= 0)
close (s->fd);
if (s->name)
free (s->name);
@@ -371,6 +372,11 @@
int32_t tmp;
ret = krb5_read_priv_message(context, s->ac, &s->fd, &out);
+ if(ret == HEIM_ERR_EOF && close(s->fd) == 0) {
+ s->flags |= SLAVE_FD_CLOSED;
+ slave_dead(s);
+ return 1;
+ }
if(ret) {
krb5_warn (context, ret, "error reading message from %s", s->name);
return 1;
@@ -566,8 +572,10 @@
max_fd = max(max_fd, listen_fd);
for (p = slaves; p != NULL; p = p->next) {
- FD_SET(p->fd, &readset);
- max_fd = max(max_fd, p->fd);
+ if (!(p->flags & SLAVE_FD_CLOSED)) {
+ FD_SET(p->fd, &readset);
+ max_fd = max(max_fd, p->fd);
+ }
}
ret = select (max_fd + 1,
@@ -605,7 +613,7 @@
}
for(p = slaves; ret && p != NULL; p = p->next)
- if (FD_ISSET(p->fd, &readset)) {
+ if (!(p->flags & SLAVE_FD_CLOSED) && FD_ISSET(p->fd, &readset)) {
--ret;
if(process_msg (context, p, log_fd, database, current_version))
slave_dead(p);