1995-09-12 03:07:18 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the ISDN master program.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1995 Matthias Urlichs.
|
|
|
|
* See the file COPYING for license details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "master.h"
|
|
|
|
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* Clone a connection info record ("conngrab" because I use it to collect
|
|
|
|
all pertinent information to grab data out of the configuration files
|
|
|
|
with), or create a new one. */
|
1995-10-29 23:31:09 +00:00
|
|
|
conngrab
|
|
|
|
Xnewgrab(conngrab master, int lin)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
conngrab slave;
|
|
|
|
|
1995-11-15 07:13:32 +00:00
|
|
|
slave = xmalloc(sizeof(*slave));
|
1995-09-12 03:07:18 +00:00
|
|
|
if(slave == NULL)
|
|
|
|
return NULL;
|
1995-10-22 10:59:20 +00:00
|
|
|
if(master == NULL) {
|
1995-09-12 03:07:18 +00:00
|
|
|
bzero(slave,sizeof(*slave));
|
1995-10-29 23:31:09 +00:00
|
|
|
slave->cclass = "*";
|
1995-10-25 12:36:04 +00:00
|
|
|
slave->mask = ~0;
|
1995-10-22 10:59:20 +00:00
|
|
|
} else {
|
1995-09-12 03:07:18 +00:00
|
|
|
if(master->refs == 0 || master->protocol == (char *)0xdeadbeef)
|
|
|
|
panic("FreeGrab");
|
|
|
|
*slave = *master;
|
|
|
|
if(slave->par_out != NULL)
|
|
|
|
slave->par_out = copybufmsg(slave->par_out);
|
|
|
|
if(slave->par_in != NULL)
|
|
|
|
slave->par_in = dupmsg(slave->par_in);
|
|
|
|
}
|
|
|
|
slave->refs = 1;
|
|
|
|
return slave;
|
|
|
|
}
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* Forget one... */
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
|
|
|
Xdropgrab(conngrab cg,int lin)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
if(cg == NULL)
|
|
|
|
return;
|
|
|
|
chkone(cg);
|
|
|
|
cg->dropline = lin;
|
|
|
|
|
|
|
|
if(--cg->refs == 0) {
|
|
|
|
chkone(cg);
|
|
|
|
if(cg->par_out != NULL)
|
|
|
|
freemsg(cg->par_out);
|
|
|
|
if(cg->par_in != NULL)
|
|
|
|
freemsg(cg->par_in);
|
|
|
|
cg->par_out = (void *)0xdeadbeef;
|
|
|
|
cg->par_in = (void *)0xdeadbeef;
|
|
|
|
cg->site = (void *)0xdeadbeef;
|
|
|
|
cg->protocol= (void *)0xdeadbeef;
|
|
|
|
cg->cclass = (void *)0xdeadbeef;
|
|
|
|
cg->card = (void *)0xdeadbeef;
|
|
|
|
chkone(cg);
|
|
|
|
free(cg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* Set the reference number. For debugging. */
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
|
|
|
Xsetconnref(const char *deb_file, unsigned int deb_line, conninfo conn, int connref)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
1995-12-06 05:06:20 +00:00
|
|
|
if(log_34 & 2)
|
|
|
|
printf("-%s:%d: SetConnRef.%p %d/%d/%ld -> %d\n",deb_file,deb_line,conn,conn->minor,conn->fminor,conn->connref,connref);
|
1995-09-12 03:07:18 +00:00
|
|
|
conn->connref = connref;
|
|
|
|
}
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* Print the text foo onto all ATL/ channels. */
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
1995-11-08 18:17:48 +00:00
|
|
|
connreport(char *foo, char *card, int minor)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
conninfo conn;
|
|
|
|
mblk_t xx;
|
|
|
|
struct datab db;
|
|
|
|
char ans[20];
|
|
|
|
xx.b_rptr = ans;
|
|
|
|
db.db_base = ans;
|
|
|
|
db.db_lim = ans + sizeof (ans);
|
|
|
|
xx.b_datap = &db;
|
|
|
|
|
1995-10-25 12:36:04 +00:00
|
|
|
for(conn = isdn4_conn; conn != NULL; conn = conn->next) {
|
1995-09-12 03:07:18 +00:00
|
|
|
struct iovec io[2];
|
|
|
|
|
|
|
|
chkone(conn);
|
1995-10-29 23:31:09 +00:00
|
|
|
if(conn->ignore < 3 || conn->minor == 0)
|
1995-09-12 03:07:18 +00:00
|
|
|
continue;
|
1995-10-29 23:31:09 +00:00
|
|
|
if(!wildmatch(conn->cardname,card))
|
|
|
|
continue;
|
1995-11-08 18:17:48 +00:00
|
|
|
if(minor != 0 && conn->minor != minor)
|
|
|
|
continue;
|
1995-10-29 23:31:09 +00:00
|
|
|
if(conn->lastMsg != NULL && !strcmp(conn->lastMsg,foo))
|
|
|
|
continue;
|
|
|
|
if(conn->lastMsg != NULL)
|
|
|
|
free(conn->lastMsg);
|
1995-11-15 07:13:32 +00:00
|
|
|
conn->lastMsg = xmalloc(strlen(foo)+1);
|
1995-10-29 23:31:09 +00:00
|
|
|
if(conn->lastMsg != NULL)
|
|
|
|
strcpy(conn->lastMsg,foo);
|
1995-09-12 03:07:18 +00:00
|
|
|
|
|
|
|
xx.b_wptr = ans;
|
|
|
|
m_putid (&xx, CMD_PROT);
|
|
|
|
m_putsx (&xx, ARG_FMINOR);
|
|
|
|
m_puti (&xx, conn->minor);
|
|
|
|
m_putdelim (&xx);
|
|
|
|
m_putid (&xx, PROTO_AT);
|
|
|
|
io[0].iov_base = xx.b_rptr;
|
|
|
|
io[0].iov_len = xx.b_wptr - xx.b_rptr;
|
|
|
|
io[1].iov_base = foo;
|
|
|
|
io[1].iov_len = strlen(foo);
|
|
|
|
(void) strwritev (xs_mon, io, 2, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* Print the state of this connection with connreport(). */
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
1995-11-08 18:17:48 +00:00
|
|
|
ReportOneConn(conninfo conn, int minor)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
1995-11-28 04:51:07 +00:00
|
|
|
char is1[15]="",sp[200], *spf = sp;
|
1996-04-11 14:53:10 +00:00
|
|
|
char cn = 1;
|
|
|
|
|
|
|
|
if(conn->cardname != NULL) {
|
|
|
|
if((conn->cardname[0] == '*') && (conn->cardname[1] == '\0'))
|
|
|
|
cn = 0;
|
|
|
|
}
|
1995-11-28 04:51:07 +00:00
|
|
|
if(conn->state != c_up) {
|
|
|
|
if(conn->retries > 0)
|
|
|
|
sprintf(is1,".%d",conn->retries);
|
|
|
|
if(conn->retiming > 0)
|
|
|
|
sprintf(is1+strlen(is1),"-%d",conn->retiming);
|
|
|
|
}
|
1995-11-08 18:17:48 +00:00
|
|
|
spf += sprintf(spf,"%s%d:%d %s %s %s %d %s%s/%s %ld %ld %s",
|
1995-09-12 03:07:18 +00:00
|
|
|
conn->ignore?"!":"", conn->minor,
|
|
|
|
conn->seqnum, conn->cg ? conn->cg->site : "-",
|
1996-02-10 16:30:05 +00:00
|
|
|
conn->cg ? conn->cg->protocol : "-",
|
|
|
|
conn->classname ? conn->classname : (conn->cg ? conn->cg->cclass : "-"),
|
1995-11-08 18:17:48 +00:00
|
|
|
conn->pid, state2str(conn->state), is1,
|
1996-04-11 14:53:10 +00:00
|
|
|
(cn && conn->cardname) ? conn->cardname : (conn->cg ? conn->cg->card : "-"),
|
1995-10-25 12:36:04 +00:00
|
|
|
conn->charge, conn->ccharge, FlagInfo(conn->flags));
|
1995-09-12 03:07:18 +00:00
|
|
|
if(conn->cg != NULL && (conn->cg->flags ^ conn->flags) != 0) {
|
|
|
|
int foo = strlen(FlagInfo(conn->cg->flags ^ conn->flags));
|
|
|
|
int bar = strlen(FlagInfo(conn->cg->flags));
|
1995-11-13 22:20:37 +00:00
|
|
|
if(foo*3 < bar*2)
|
1995-09-12 03:07:18 +00:00
|
|
|
spf += sprintf(spf, "^%s",FlagInfo(conn->cg->flags ^ conn->flags));
|
|
|
|
else
|
|
|
|
spf += sprintf(spf, "/%s",FlagInfo(conn->cg->flags));
|
|
|
|
}
|
|
|
|
if(conn->cg != NULL && conn->cg->nr != NULL)
|
|
|
|
spf += sprintf(spf, ",%s",conn->cg->nr);
|
|
|
|
else if(conn->cg != NULL && conn->cg->oldnr != NULL)
|
|
|
|
spf += sprintf(spf, ",%s",conn->cg->oldnr);
|
|
|
|
if(conn->cg != NULL && conn->cg->lnr != NULL)
|
|
|
|
spf += sprintf(spf, ";%s",conn->cg->lnr);
|
|
|
|
else if(conn->cg != NULL && conn->cg->oldlnr != NULL)
|
|
|
|
spf += sprintf(spf, ";%s",conn->cg->oldlnr);
|
|
|
|
spf += sprintf(spf," %s", CauseInfo(conn->cause, conn->causeInfo));
|
1995-11-08 18:17:48 +00:00
|
|
|
connreport(sp,(conn->cg ? conn->cg->card : "*"),minor);
|
|
|
|
}
|
|
|
|
|
1996-07-25 07:59:47 +00:00
|
|
|
static void nodown(conninfo conn)
|
|
|
|
{
|
|
|
|
syslog(LOG_CRIT,"Verbindung geht nicht runter! Problem! Nothalt wegen %s!", conn->cg ? conn->cg->site : "???");
|
|
|
|
_exit(10);
|
|
|
|
}
|
|
|
|
|
1995-11-13 22:20:37 +00:00
|
|
|
static inline int retimeout(conninfo conn)
|
1995-11-08 18:17:48 +00:00
|
|
|
{
|
1995-11-13 22:20:37 +00:00
|
|
|
int tim = 0;
|
1995-11-08 18:17:48 +00:00
|
|
|
/* Exponential backoff. Sorry but this is necessary. */
|
1996-02-10 16:30:05 +00:00
|
|
|
conn->retiming++;
|
1995-11-08 18:17:48 +00:00
|
|
|
if(conn->charge != 0)
|
1996-02-10 16:30:05 +00:00
|
|
|
tim = 5*60*(1<<conn->retiming);
|
1995-11-08 18:17:48 +00:00
|
|
|
else if (conn->cause == ID_priv_Busy)
|
1996-02-10 16:30:05 +00:00
|
|
|
tim = 5*(1<<(conn->retiming/6));
|
1995-11-08 18:17:48 +00:00
|
|
|
else if(conn->flags & F_FASTREDIAL)
|
1996-02-10 16:30:05 +00:00
|
|
|
tim = 2+(1<<(conn->retiming/4));
|
1995-11-08 18:17:48 +00:00
|
|
|
else
|
1996-02-10 16:30:05 +00:00
|
|
|
tim = 5+(1<<(conn->retiming/2));
|
1995-11-13 22:20:37 +00:00
|
|
|
if((tim <= 0) || (tim > 60*60*2))
|
|
|
|
tim = 60*60*2;
|
|
|
|
return tim;
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* Sets the state of a connection; does all the housekeeping associated
|
|
|
|
with the change. */
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
|
|
|
Xsetconnstate(const char *deb_file, unsigned int deb_line,conninfo conn, CState state)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
chkone(conn);
|
1995-12-06 05:06:20 +00:00
|
|
|
if(log_34 & 2) {
|
|
|
|
printf("%s:%d: State %d: %s",deb_file,deb_line,conn->minor,state2str(conn->state));
|
|
|
|
if(conn->state != state)
|
|
|
|
printf(" -> %s\n",state2str(state));
|
|
|
|
else
|
|
|
|
printf("\n");
|
|
|
|
}
|
1995-11-08 18:17:48 +00:00
|
|
|
if(conn->timer_reconn && (state == c_off || state == c_offdown || (state >= c_going_up
|
1995-09-12 03:07:18 +00:00
|
|
|
&& conn->state < c_going_up))) {
|
|
|
|
conn->timer_reconn = 0;
|
|
|
|
untimeout(time_reconn,conn);
|
1995-11-08 18:17:48 +00:00
|
|
|
} else if(!conn->timer_reconn && state != c_off && state < c_going_up && conn->state >= c_going_up) {
|
1995-09-12 03:07:18 +00:00
|
|
|
if(conn->want_fast_reconn) {
|
|
|
|
conn->want_fast_reconn = 0;
|
|
|
|
} else {
|
|
|
|
conn->timer_reconn = 1;
|
|
|
|
if(conn->flags & F_FASTREDIAL)
|
|
|
|
timeout(time_reconn,conn,HZ);
|
1996-02-10 16:30:05 +00:00
|
|
|
else if(conn->flags & F_FORCEIN)
|
|
|
|
timeout(time_reconn,conn,30*HZ);
|
1995-09-12 03:07:18 +00:00
|
|
|
else
|
1996-02-10 16:30:05 +00:00
|
|
|
timeout(time_reconn,conn,6*HZ);
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
|
|
|
}
|
1995-11-13 22:20:37 +00:00
|
|
|
|
|
|
|
if(conn->cg != NULL) {
|
|
|
|
if(state == c_up) {
|
|
|
|
conn->cg->d_level = 0;
|
|
|
|
conn->cg->d_nextlevel = 0;
|
|
|
|
} else if(state == c_off) {
|
|
|
|
if(conn->cg->d_level < conn->cg->d_nextlevel) {
|
|
|
|
conn->cg->d_level = conn->cg->d_nextlevel;
|
|
|
|
state = c_down;
|
1995-11-28 04:51:07 +00:00
|
|
|
conn->retries = 0;
|
|
|
|
} else {
|
|
|
|
conn->cg->d_level = 0;
|
|
|
|
conn->cg->d_nextlevel = 0;
|
1995-11-13 22:20:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1995-11-28 04:51:07 +00:00
|
|
|
if((conn->minor > 0) && (conn->flags & F_PERMANENT)) {
|
1995-11-13 22:20:37 +00:00
|
|
|
if((conn->state >= c_down) && (state <= c_off) && conn->sentsetup) {
|
|
|
|
mblk_t *mb = allocb(30,BPRI_MED);
|
|
|
|
if(mb != NULL) {
|
|
|
|
int xlen;
|
|
|
|
|
|
|
|
m_putid (mb, CMD_PROT);
|
|
|
|
m_putsx (mb, ARG_MINOR);
|
|
|
|
m_puti (mb, conn->minor);
|
|
|
|
m_putdelim (mb);
|
|
|
|
m_putid (mb, PROTO_DISABLE);
|
|
|
|
xlen = mb->b_wptr - mb->b_rptr;
|
|
|
|
DUMPW (mb->b_rptr, xlen);
|
|
|
|
(void) strwrite (xs_mon, (uchar_t *) mb->b_rptr, xlen, 1);
|
|
|
|
freemsg(mb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-12-22 07:53:59 +00:00
|
|
|
if((conn->state >= c_off) && (state == c_down) && conn->sentsetup) {
|
1995-11-13 22:20:37 +00:00
|
|
|
mblk_t *mb = allocb(30,BPRI_MED);
|
|
|
|
if(mb != NULL) {
|
|
|
|
int xlen;
|
|
|
|
|
|
|
|
m_putid (mb, CMD_PROT);
|
|
|
|
m_putsx (mb, ARG_MINOR);
|
|
|
|
m_puti (mb, conn->minor);
|
|
|
|
m_putdelim (mb);
|
|
|
|
m_putid (mb, PROTO_ENABLE);
|
|
|
|
xlen = mb->b_wptr - mb->b_rptr;
|
|
|
|
DUMPW (mb->b_rptr, xlen);
|
|
|
|
(void) strwrite (xs_mon, (uchar_t *) mb->b_rptr, xlen, 1);
|
|
|
|
freemsg(mb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if((conn->state < c_up) && (state == c_up))
|
1995-11-28 04:51:07 +00:00
|
|
|
pushprot(conn->cg,conn->minor,conn->connref,PUSH_UPDATE);
|
1995-11-13 22:20:37 +00:00
|
|
|
}
|
|
|
|
|
1995-10-25 12:36:04 +00:00
|
|
|
#if 0
|
1995-09-12 03:07:18 +00:00
|
|
|
if(conn->state <= c_down)
|
|
|
|
setconnref(conn,0);
|
1995-10-25 12:36:04 +00:00
|
|
|
#endif
|
1995-12-07 04:58:52 +00:00
|
|
|
if(state == c_up) {
|
1995-09-12 03:07:18 +00:00
|
|
|
conn->cause = 0;
|
1995-12-07 04:58:52 +00:00
|
|
|
conn->upwhen = time(NULL);
|
1996-04-21 10:53:01 +00:00
|
|
|
conn->did_bounce = 0;
|
1995-12-07 04:58:52 +00:00
|
|
|
}
|
1996-04-21 10:53:01 +00:00
|
|
|
else if(state == c_going_up) {
|
1995-09-12 03:07:18 +00:00
|
|
|
conn->cause = 999999;
|
1996-04-21 10:53:01 +00:00
|
|
|
conn->did_bounce = 1;
|
|
|
|
}
|
1996-07-25 07:59:47 +00:00
|
|
|
if(conn->state == c_up && state < c_up) {
|
|
|
|
int conntime = time(NULL) - conn->upwhen;
|
|
|
|
if(conn->cg != NULL)
|
|
|
|
syslog(LOG_INFO,"CONN %s:%s %ld",conn->cg->site,conn->cg->protocol,conntime);
|
|
|
|
else
|
|
|
|
syslog(LOG_WARNING,"CONN ??? %ld",conntime);
|
|
|
|
}
|
1995-12-06 05:06:20 +00:00
|
|
|
if((conn->state < c_going_down && state > c_going_down) || state < c_off) {
|
1995-09-12 03:07:18 +00:00
|
|
|
if(conn->charge > 0) {
|
|
|
|
if(conn->cg != NULL)
|
1995-12-06 05:06:20 +00:00
|
|
|
syslog((state > c_going_down) ? LOG_INFO : LOG_WARNING,"COST %s:%s %ld",conn->cg->site,conn->cg->protocol,conn->charge);
|
1995-09-12 03:07:18 +00:00
|
|
|
else
|
|
|
|
syslog(LOG_WARNING,"COST ??? %ld",conn->charge);
|
1995-12-22 07:53:59 +00:00
|
|
|
run_rp(conn,'l');
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
|
|
|
conn->ccharge += conn->charge;
|
|
|
|
conn->charge = 0;
|
|
|
|
}
|
|
|
|
if(conn->cg != NULL) {
|
|
|
|
if(conn->state == c_off && state > c_off) {
|
|
|
|
kill_rp(conn,'x');
|
|
|
|
run_rp(conn,'y');
|
|
|
|
}
|
|
|
|
if(conn->state > c_off && state == c_off) {
|
|
|
|
kill_rp(conn,'y');
|
|
|
|
run_rp(conn,'x');
|
|
|
|
}
|
|
|
|
if(conn->state != c_up && state == c_up) {
|
|
|
|
kill_rp(conn,'d');
|
|
|
|
kill_rp(conn,'f');
|
|
|
|
run_rp(conn,'u');
|
|
|
|
}
|
|
|
|
if(conn->state == c_up && state != c_up) {
|
|
|
|
kill_rp(conn,'u');
|
|
|
|
run_rp(conn,'d');
|
|
|
|
}
|
|
|
|
if(conn->state == c_going_up && state <= c_going_down) {
|
|
|
|
kill_rp(conn,'u');
|
|
|
|
run_rp(conn,'f');
|
|
|
|
}
|
1996-02-10 16:30:05 +00:00
|
|
|
if(conn->state > c_forceoff && state <= c_forceoff && conn->pid != 0) {
|
1995-09-12 03:07:18 +00:00
|
|
|
struct conninfo *xconn;
|
1995-11-15 07:13:32 +00:00
|
|
|
xconn = xmalloc(sizeof(*xconn));
|
1995-09-12 03:07:18 +00:00
|
|
|
if(xconn != NULL) {
|
|
|
|
bzero(xconn,sizeof(*xconn));
|
|
|
|
xconn->seqnum = ++connseq;
|
|
|
|
xconn->cause = ID_priv_Print;
|
|
|
|
xconn->causeInfo = "Sig TERM (force off)";
|
|
|
|
xconn->pid = conn->pid;
|
|
|
|
conn->cg->refs++;
|
|
|
|
/* dropgrab(conn->cg; ** is new anyway */
|
|
|
|
xconn->cg = conn->cg;
|
1995-10-25 12:36:04 +00:00
|
|
|
xconn->next = isdn4_conn; isdn4_conn = xconn;
|
1995-09-12 03:07:18 +00:00
|
|
|
dropconn(xconn);
|
|
|
|
}
|
|
|
|
kill(conn->pid,SIGTERM);
|
|
|
|
conn->pid = 0;
|
|
|
|
}
|
|
|
|
}
|
1996-07-25 07:59:47 +00:00
|
|
|
if(conn->state != c_going_down && state == c_going_down)
|
|
|
|
timeout(nodown,conn,10*HZ);
|
|
|
|
else if(conn->state == c_going_down && state != c_going_down)
|
|
|
|
untimeout(nodown,conn);
|
1995-11-28 04:51:07 +00:00
|
|
|
if(conn->state == c_off && state > c_off) {
|
|
|
|
conn->retries = 0;
|
|
|
|
conn->want_reconn = 0;
|
|
|
|
}
|
|
|
|
|
1996-04-11 14:53:10 +00:00
|
|
|
if((conn->state != c_down) || (state != c_going_down))
|
|
|
|
conn->state=state; /* ^^- prevents spurious messages */
|
|
|
|
|
1995-09-12 03:07:18 +00:00
|
|
|
if(conn->ignore < 2)
|
|
|
|
ReportConn(conn);
|
|
|
|
if(state <= c_down)
|
|
|
|
conn->connref = 0;
|
|
|
|
if(conn->ignore)
|
|
|
|
return;
|
|
|
|
if(state == c_down && conn->want_reconn) {
|
|
|
|
conn->want_reconn--;
|
|
|
|
try_reconn(conn);
|
|
|
|
} else if(state == c_up) {
|
|
|
|
conn->retries = 0;
|
|
|
|
conn->retiming = 0;
|
|
|
|
conn->want_reconn = 0;
|
|
|
|
}
|
|
|
|
if((state == c_off) && !conn->retime && (conn->flags & F_PERMANENT)) {
|
|
|
|
conn->retime = 1;
|
1995-11-08 18:17:48 +00:00
|
|
|
timeout(retime,conn,retimeout(conn)*HZ);
|
1995-11-28 04:51:07 +00:00
|
|
|
} else if((state > c_off) && conn->retime) {
|
1995-09-12 03:07:18 +00:00
|
|
|
conn->retime = 0;
|
|
|
|
untimeout(retime,conn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* "rdrop" means "really drop". */
|
1995-09-12 03:07:18 +00:00
|
|
|
void rdropconn (struct conninfo *conn, int deb_line) {
|
|
|
|
conn->ignore=2; dropconn(conn); }
|
|
|
|
|
|
|
|
void
|
1995-10-22 10:59:20 +00:00
|
|
|
Xdropconn (struct conninfo *conn, const char *deb_file, unsigned int deb_line)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
chkone(conn);
|
|
|
|
if(conn->locked) {
|
1995-11-08 18:17:48 +00:00
|
|
|
if(log_34 & 2)printf ("DropConn %s:%d: LOCK %d/%d/%ld\n", deb_file,deb_line, conn->minor, conn->fminor, conn->connref);
|
1995-09-12 03:07:18 +00:00
|
|
|
return;
|
|
|
|
}
|
1995-11-08 18:17:48 +00:00
|
|
|
if(log_34 & 2)printf ("DropConn %s:%d: %d/%d/%ld\n", deb_file,deb_line, conn->minor, conn->fminor, conn->connref);
|
1995-09-12 03:07:18 +00:00
|
|
|
if(!conn->ignore) {
|
|
|
|
conn->ignore=1;
|
1996-02-10 16:30:05 +00:00
|
|
|
setconnstate(conn,c_unknown);
|
1995-09-12 03:07:18 +00:00
|
|
|
#if 0
|
|
|
|
if(conn->state > c_off)
|
|
|
|
setconnstate(conn, c_off);
|
|
|
|
else
|
|
|
|
ReportConn(conn);
|
|
|
|
#endif
|
1995-10-22 10:59:20 +00:00
|
|
|
timeout(rdropconn,conn,HZ*60*5); /* Drop the record after five minutes */
|
1995-09-12 03:07:18 +00:00
|
|
|
return;
|
1995-10-22 10:59:20 +00:00
|
|
|
} else if(conn->ignore == 1) { /* already going to drop it */
|
1996-02-10 16:30:05 +00:00
|
|
|
setconnstate(conn,c_unknown);
|
1995-09-12 03:07:18 +00:00
|
|
|
return;
|
|
|
|
} else
|
1996-02-10 16:30:05 +00:00
|
|
|
setconnstate(conn,c_unknown);
|
1995-10-22 10:59:20 +00:00
|
|
|
|
|
|
|
{ /* unchain the conn from the list */
|
|
|
|
/* Could use a doubly-linked list here, but what the ... */
|
1995-10-25 12:36:04 +00:00
|
|
|
struct conninfo **pconn = &isdn4_conn;
|
1995-10-22 10:59:20 +00:00
|
|
|
while(*pconn != NULL) {
|
|
|
|
if(*pconn == conn) {
|
|
|
|
*pconn = conn->next;
|
1995-09-12 03:07:18 +00:00
|
|
|
break;
|
|
|
|
}
|
1995-10-22 10:59:20 +00:00
|
|
|
pconn = &(*pconn)->next;
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
1995-10-22 10:59:20 +00:00
|
|
|
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
struct proginfo *run;
|
|
|
|
|
|
|
|
for (run = conn->run; run != NULL; run = run->next) {
|
|
|
|
if(strchr(run->type,'s') == NULL)
|
|
|
|
kill(run->pid,SIGQUIT);
|
|
|
|
run->master = NULL;
|
|
|
|
}
|
|
|
|
}
|
1995-10-22 10:59:20 +00:00
|
|
|
{ /* Say that we forgot the thing. */
|
1995-09-12 03:07:18 +00:00
|
|
|
char xs[10];
|
|
|
|
sprintf(xs,"-%d",conn->seqnum);
|
1995-11-08 18:17:48 +00:00
|
|
|
connreport(xs,conn->cg ? conn->cg->card : "*",0);
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
1996-02-10 16:30:05 +00:00
|
|
|
printf("Drop %p %s:%d\n",conn,deb_file,deb_line);
|
1995-09-12 03:07:18 +00:00
|
|
|
dropgrab(conn->cg);
|
1995-10-29 23:31:09 +00:00
|
|
|
if(conn->lastMsg != NULL)
|
|
|
|
free(conn->lastMsg);
|
1995-09-12 03:07:18 +00:00
|
|
|
free(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
|
|
|
retime(struct conninfo *conn)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
if(conn->retime) {
|
|
|
|
conn->retime = 0;
|
1995-11-28 04:51:07 +00:00
|
|
|
if(conn->state == c_off)
|
|
|
|
setconnstate(conn,c_down);
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
|
|
|
time_reconn(struct conninfo *conn)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
if(conn->timer_reconn) {
|
|
|
|
conn->timer_reconn = 0;
|
|
|
|
if(conn->want_reconn)
|
|
|
|
try_reconn(conn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-10-22 10:59:20 +00:00
|
|
|
/* Reestablish a connection, eg. because data are to be transmitted. */
|
1995-10-29 23:31:09 +00:00
|
|
|
void
|
|
|
|
try_reconn(struct conninfo *conn)
|
1995-09-12 03:07:18 +00:00
|
|
|
{
|
|
|
|
mblk_t *md;
|
|
|
|
|
|
|
|
chkone(conn);
|
|
|
|
if(conn == NULL || conn->state <= c_off)
|
|
|
|
return;
|
|
|
|
if(conn->state != c_down && conn->state != c_up) {
|
|
|
|
if(!(conn->want_reconn))
|
|
|
|
conn->want_reconn = 2;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(conn->timer_reconn) {
|
|
|
|
if(!(conn->want_reconn))
|
|
|
|
conn->want_reconn = 2;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(conn->state != c_down)
|
|
|
|
return;
|
|
|
|
|
|
|
|
md = allocb(256,BPRI_LO);
|
|
|
|
if(md != NULL) {
|
|
|
|
conngrab cg = conn->cg;
|
|
|
|
struct conninfo *xconn;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
if(cg == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
chkone(cg);
|
|
|
|
cg->refs++;
|
|
|
|
|
1995-10-25 12:36:04 +00:00
|
|
|
if(conn->want_reconn < MAX_RECONN) { /* if ==, we have a direct callback */
|
|
|
|
cg->nr = NULL; cg->nrsuf = NULL;
|
|
|
|
cg->flags &=~F_NRCOMPLETE;
|
1995-10-29 23:31:09 +00:00
|
|
|
}
|
1995-09-12 03:07:18 +00:00
|
|
|
cg->lnr = NULL; cg->lnrsuf = NULL;
|
1995-10-25 12:36:04 +00:00
|
|
|
cg->card = conn->cardname ? conn->cardname : "*";
|
|
|
|
cg->cclass = conn->classname ? conn->classname : "*";
|
1995-12-07 16:27:01 +00:00
|
|
|
cg->flags &=~(F_INCOMING|F_OUTCOMPLETE|F_LNRCOMPLETE);
|
1995-09-12 03:07:18 +00:00
|
|
|
cg->flags |= F_OUTGOING;
|
1995-12-07 16:27:01 +00:00
|
|
|
|
|
|
|
/* If more than one bit is set, this is true. */
|
|
|
|
if((cg->flags & F_MASKFLAGS) & ((cg->flags & F_MASKFLAGS) - 1))
|
|
|
|
cg->flags &= ~F_MASKFLAGS;
|
1995-09-12 03:07:18 +00:00
|
|
|
if(cg->par_out != NULL)
|
|
|
|
freemsg(cg->par_out);
|
|
|
|
if((cg->par_out = allocb(256,BPRI_LO)) == NULL) {
|
|
|
|
dropgrab(cg);
|
|
|
|
freeb(md);
|
1995-11-13 22:20:37 +00:00
|
|
|
conn->cause = ID_priv_Print;
|
|
|
|
conn->causeInfo = "NoMem";
|
|
|
|
setconnstate(conn,c_off);
|
1995-09-12 03:07:18 +00:00
|
|
|
}
|
|
|
|
if(cg->par_in != NULL) {
|
|
|
|
freemsg(cg->par_in);
|
|
|
|
cg->par_in = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* anything else is added by startconn */
|
|
|
|
|
1995-11-02 09:15:35 +00:00
|
|
|
if((xconn = startconn(cg,0,0, &ret, NULL)) == conn) {
|
1995-09-12 03:07:18 +00:00
|
|
|
dropgrab(cg);
|
|
|
|
freeb(md);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dropgrab(cg);
|
|
|
|
if(ret != NULL) {
|
|
|
|
if(!strcmp(ret,"0BUSY")) {
|
|
|
|
conn->cause = ID_priv_Busy;
|
|
|
|
} else {
|
|
|
|
conn->cause = ID_priv_Print;
|
|
|
|
conn->causeInfo = ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setconnstate(conn,c_off);
|
|
|
|
freeb(md);
|
|
|
|
} else
|
|
|
|
setconnstate(conn,c_off);
|
|
|
|
}
|
|
|
|
|
|
|
|
|