Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Nov 1998 01:47:08 +0100 (CET)
From:      Mikael Karpberg <karpen@ocean.campus.luth.se>
To:        brian@Awfulhak.org (Brian Somers)
Cc:        marcs@znep.com, brian@Awfulhak.org, freebsd-hackers@FreeBSD.ORG
Subject:   Re: bind()/listen() race
Message-ID:  <199811100047.BAA08580@ocean.campus.luth.se>
In-Reply-To: <199811100007.AAA02529@woof.lan.awfulhak.org> from Brian Somers at "Nov 10, 98 00:07:38 am"

next in thread | previous in thread | raw e-mail | index | archive | help
According to Brian Somers:
> > You suggestion is possible as a workaround, and is probably the easiest
> > fix.
> 
> It maybe the only practical one too.  Backing off for a second and 
> trying again will give us a situation where we can fail due to a 
> previously crashed ppp (or maybe even resurrect the socket), or we 
> get a connection....  We'd be extremely unlikely to have had a whole 
> second between a bind() and listen() :-)  If another ppp actually 
> came up and went down again in that second, then we're probably going 
> to do the same thing - due to authentication or IPCP negotiation 
> failure (misconfiguration).
> 
> I appreciate that some sort of elaborate read-lock-promoted
> -to-write-lock on the server side would allow the client to say ``if 
> there's a write lock, connect(), otherwise if there's no read lock 
> the server's dead - but this may be overkill....  The simpler the 
> better.

Well... if you use a softlink (/var/run/mpppd.lock, or something?) which
points to the PID for the holder...

How about something like this?

int tmp, i_am_server = 0;
while ((tmp = create_softlink_to_pid()) == failure) {
  if (kill_pid_with_signal_0() == success)
     break;
  remove_softlink();  /* lock was old */
}
if (tmp == failure) {  /* we're not master */
  tmp = 0;
  while (connect() == failed && ++tmp < 10) {
    sched_yield();
    /* maybe add a "select(0,0,0,timeout);" with a small timeout too */
  }
  if (tmp == 10)
    panic();
} else {                /* we are master */
  if (bind() = failed)
    panic();
  else
    listen();
  i_am_server = 1;
}

Wouldn't that maybe work?
Anyway, just brainstorming...  Goodnight.

  /Mikael

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199811100047.BAA08580>