o Call bundle_LinkClosed() when transferring a datalink so that

the bundle has the opportunity to go PHASE_DEAD and cleanup
  the interface (if it's the last link).
o Regnerate our phys_type value when we transfer the link.
o Always clean up the interface when destroying our bundle in case
  we're abending.
o Always clean up our interface when the last link is gone rather than
  delaying things 'till exit time in the -direct case (the interface
  is useless anyway).  Do this *after* slamming down our NCPs (if
  they're still around).
o Our MP server descriptor now clears the relevent device descriptor
  from our descriptor [fd]sets when a datalink is on death-row (to
  be transferred to another running ppp), thus avoiding the possibility
  of passing a bum descriptor to select() and having ppp abend.
o Handle the MP socket descriptor functions from within the bundle
  descriptor functions.  Now we ensure that the MP socket descriptor
  functions see the descriptor sets *after* they've been seen by our
  datalinks.
o Add/fix a few more comments.
This commit is contained in:
Brian Somers 1998-05-15 18:21:45 +00:00
parent 0a1b5c9d9e
commit ea7229694b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=36076
7 changed files with 81 additions and 26 deletions

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bundle.c,v 1.1.2.81 1998/05/10 22:20:06 brian Exp $
* $Id: bundle.c,v 1.1.2.82 1998/05/11 23:39:27 brian Exp $
*/
#include <sys/types.h>
@ -381,6 +381,13 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
result++;
}
/*
* This *MUST* be called after the datalink UpdateSet()s as it
* might be ``holding'' one of the datalinks and wants to be
* able to de-select() from the descriptor set
*/
descriptor_UpdateSet(&bundle->ncp.mp.server.desc, r, w, e, n);
return result;
}
@ -409,6 +416,9 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
struct datalink *dl;
struct descriptor *desc;
if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
descriptor_Read(&bundle->ncp.mp.server.desc, bundle, fdset);
for (dl = bundle->links; dl; dl = dl->next)
if (descriptor_IsSet(&dl->desc, fdset))
descriptor_Read(&dl->desc, bundle, fdset);
@ -502,6 +512,10 @@ bundle_DescriptorWrite(struct descriptor *d, struct bundle *bundle,
struct datalink *dl;
struct descriptor *desc;
/* This is not actually necessary as struct mpserver doesn't Write() */
if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset))
descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset);
for (dl = bundle->links; dl; dl = dl->next)
if (descriptor_IsSet(&dl->desc, fdset))
descriptor_Write(&dl->desc, bundle, fdset);
@ -704,20 +718,24 @@ bundle_Destroy(struct bundle *bundle)
struct datalink *dl;
struct descriptor *desc, *ndesc;
/* In case we're dropping out with an exception :-O */
/*
* Clean up the interface. We don't need to mp_Down(),
* ipcp_CleanInterface() and bundle_DownInterface() unless we're getting
* out under exceptional conditions such as a descriptor exception.
*/
mp_Down(&bundle->ncp.mp);
if (bundle->phys_type & PHYS_DEMAND) {
ipcp_CleanInterface(&bundle->ncp.ipcp);
bundle_DownInterface(bundle);
}
ipcp_CleanInterface(&bundle->ncp.ipcp);
bundle_DownInterface(bundle);
/* Again, these are all DATALINK_CLOSED unless we're abending */
dl = bundle->links;
while (dl)
dl = datalink_Destroy(dl);
/* In case we never made PHASE_NETWORK */
bundle_Notify(bundle, EX_ERRDEAD);
/* Finally, destroy our prompts */
desc = bundle->desc.next;
while (desc) {
ndesc = desc->next;
@ -858,8 +876,11 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
{
/*
* Our datalink has closed.
* UpdateSet() will remove 1OFF and STDIN links.
* CleanDatalinks() (called from DoLoop()) will remove closed
* 1OFF and DIRECT links.
* If it's the last data link, enter phase DEAD.
*
* NOTE: dl may not be in our list (bundle_SendDatalink()) !
*/
struct datalink *odl;
@ -871,13 +892,12 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
other_links++;
if (!other_links) {
if (dl->physical->type != PHYS_DEMAND)
bundle_DownInterface(bundle);
if (bundle->ncp.ipcp.fsm.state > ST_CLOSED ||
bundle->ncp.ipcp.fsm.state == ST_STARTING) {
fsm_Down(&bundle->ncp.ipcp.fsm);
fsm_Close(&bundle->ncp.ipcp.fsm); /* ST_INITIAL please */
}
bundle_DownInterface(bundle);
bundle_NewPhase(bundle, PHASE_DEAD);
bundle_DisplayPrompt(bundle);
}
@ -1314,6 +1334,9 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
break;
}
bundle_GenPhysType(bundle);
bundle_LinkClosed(bundle, dl);
/* Build our scatter/gather array */
iov[0].iov_len = strlen(Version) + 1;
iov[0].iov_base = strdup(Version);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: datalink.c,v 1.1.2.59 1998/05/11 23:39:29 brian Exp $
* $Id: datalink.c,v 1.1.2.60 1998/05/15 18:21:02 brian Exp $
*/
#include <sys/types.h>
@ -301,15 +301,18 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
case DATALINK_LCP:
case DATALINK_AUTH:
case DATALINK_OPEN:
if (dl == dl->bundle->ncp.mp.server.send.dl)
/* Never read our descriptor if we're scheduled for transfer */
r = NULL;
result = descriptor_UpdateSet(&dl->physical->desc, r, w, e, n);
break;
}
return result;
}
int
datalink_RemoveFromSet(struct datalink *dl, fd_set *r, fd_set *w, fd_set *e)
{
return physical_RemoveFromSet(dl->physical, r, w, e);
}
static int
datalink_IsSet(struct descriptor *d, const fd_set *fdset)
{
@ -453,7 +456,7 @@ datalink_AuthOk(struct datalink *dl)
/* we've authenticated in multilink mode ! */
switch (mp_Up(&dl->bundle->ncp.mp, dl)) {
case MP_LINKSENT:
/* We've handed the link off to another ppp ! */
/* We've handed the link off to another ppp (well, we will soon) ! */
return;
case MP_UP:
/* First link in the bundle */

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: datalink.h,v 1.1.2.22 1998/05/02 21:57:45 brian Exp $
* $Id: datalink.h,v 1.1.2.23 1998/05/06 23:49:33 brian Exp $
*/
#define DATALINK_CLOSED (0)
@ -124,3 +124,5 @@ extern int datalink_SetRedial(struct cmdargs const *);
extern int datalink_SetReconnect(struct cmdargs const *);
extern const char *datalink_State(struct datalink *);
extern char *datalink_NextName(struct datalink *);
extern int datalink_RemoveFromSet(struct datalink *, fd_set *, fd_set *,
fd_set *);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.c,v 1.121.2.58 1998/05/08 18:50:21 brian Exp $
* $Id: main.c,v 1.121.2.59 1998/05/10 22:20:09 brian Exp $
*
* TODO:
*/
@ -476,8 +476,6 @@ DoLoop(struct bundle *bundle, struct prompt *prompt)
descriptor_UpdateSet(&bundle->desc, &rfds, &wfds, &efds, &nfds);
descriptor_UpdateSet(&server.desc, &rfds, &wfds, &efds, &nfds);
descriptor_UpdateSet(&bundle->ncp.mp.server.desc, &rfds, &wfds,
&efds, &nfds);
if (bundle_IsDead(bundle))
/* Don't select - we'll be here forever */
@ -536,9 +534,6 @@ DoLoop(struct bundle *bundle, struct prompt *prompt)
if (i <= nfds)
break;
if (descriptor_IsSet(&bundle->ncp.mp.server.desc, &rfds))
descriptor_Read(&bundle->ncp.mp.server.desc, bundle, &rfds);
if (descriptor_IsSet(&server.desc, &rfds))
descriptor_Read(&server.desc, bundle, &rfds);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp.c,v 1.1.2.27 1998/05/10 22:20:11 brian Exp $
* $Id: mp.c,v 1.1.2.28 1998/05/15 18:21:09 brian Exp $
*/
#include <sys/types.h>
@ -842,11 +842,14 @@ mpserver_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
if (!link_QueueLen(&s->send.dl->physical->link) &&
!s->send.dl->physical->out) {
/* Only send if we've transmitted all our data (i.e. the ConfigAck) */
datalink_RemoveFromSet(s->send.dl, r, w, e);
bundle_SendDatalink(s->send.dl, s->fd, &s->socket);
s->send.dl = NULL;
close(s->fd);
s->fd = -1;
}
} else
/* Never read from a datalink that's on death row ! */
datalink_RemoveFromSet(s->send.dl, r, NULL, NULL);
} else if (r && s->fd >= 0) {
if (*n < s->fd + 1)
*n = s->fd + 1;

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: physical.c,v 1.1.2.30 1998/05/01 19:25:35 brian Exp $
* $Id: physical.c,v 1.1.2.31 1998/05/10 22:20:14 brian Exp $
*
*/
@ -150,6 +150,33 @@ physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
return sets;
}
int
physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e)
{
int sets;
sets = 0;
if (p->fd >= 0) {
if (r && FD_ISSET(p->fd, r)) {
FD_CLR(p->fd, r);
log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd);
sets++;
}
if (e && FD_ISSET(p->fd, e)) {
FD_CLR(p->fd, e);
log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd);
sets++;
}
if (w && FD_ISSET(p->fd, w)) {
FD_CLR(p->fd, w);
log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd);
sets++;
}
}
return sets;
}
int
physical_IsSet(struct descriptor *d, const fd_set *fdset)
{

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: physical.h,v 1.1.2.23 1998/05/01 19:22:23 brian Exp $
* $Id: physical.h,v 1.1.2.24 1998/05/01 19:25:37 brian Exp $
*
*/
@ -96,3 +96,5 @@ extern int physical_UpdateSet(struct descriptor *, fd_set *, fd_set *,
extern int physical_IsSet(struct descriptor *, const fd_set *);
extern void physical_Login(struct physical *, const char *);
extern void physical_Logout(struct physical *);
extern int physical_RemoveFromSet(struct physical *, fd_set *, fd_set *,
fd_set *);