Start binkp PLZ option

This commit is contained in:
Michiel Broek 2004-01-25 13:42:05 +00:00
parent acab7aa5e8
commit 839e61c60b
4 changed files with 162 additions and 29 deletions

View File

@ -131,7 +131,8 @@ struct binkprec {
int Major; /* Major protocol version */
int Minor; /* Minor protocol version */
unsigned char *MD_Challenge; /* Received challenge data */
int PLZflag; /* Zlib packet compression */
/* Receiver buffer */
char *rxbuf; /* Receiver buffer */
int GotFrame; /* Frame complete flag */
@ -181,7 +182,7 @@ int binkp_send_command(int, ...); /* Send command frame */
void binkp_settimer(int); /* Set timeout timer */
int binkp_expired(void); /* Timer expired? */
int binkp_banner(void); /* Send system banner */
int binkp_recv_command(char *, int *, int *); /* Receive command frame */
int binkp_recv_command(char *, unsigned long *, int *); /* Receive command frame */
void parse_m_nul(char *); /* Parse M_NUL message */
int binkp_poll_frame(void); /* Poll for a frame */
void binkp_add_message(char *frame); /* Add cmd frame to queue */
@ -230,6 +231,11 @@ int binkp(int role)
bp.local_EOB = FALSE;
bp.remote_EOB = FALSE;
bp.msgs_on_queue = 0;
#ifdef HAVE_ZLIB_H
bp.PLZflag = WeCan;
#else
bp.PLZflag = No;
#endif
if (role == 1) {
if (orgbinkp()) {
@ -304,11 +310,12 @@ SM_NAMES
(char *)"WaitOk",
(char *)"Opts"
SM_EDECL
faddr *primary;
char *p, *q, *pwd;
int i, rc = 0, bufl, cmd, dupe, SendPass = FALSE, akas = 0;
fa_list **tmp, *tmpa;
faddr *fa, ra;
faddr *primary;
char *p, *q, *pwd;
int i, rc = 0, cmd, dupe, SendPass = FALSE, akas = 0;
unsigned long bufl;
fa_list **tmp, *tmpa;
faddr *fa, ra;
SM_START(ConnInit)
@ -323,10 +330,18 @@ SM_STATE(WaitConn)
IsDoing("Connect binkp %s", ascfnode(remote->addr, 0xf));
/*
* Build options we want (Add PLZ etc).
* Build options we want
*/
p = xstrcpy((char *)"OPT");
#ifdef HAVE_ZLIB_H
if (bp.PLZflag == WeCan) {
p = xstrcat(p, (char *)" PLZ");
bp.PLZflag = WeWant;
Syslog('b', "PLZflag WeCan => WeWant");
}
#endif
if (strcmp(p, (char *)"OPT"))
rc = binkp_send_command(MM_NUL, p);
free(p);
@ -576,6 +591,7 @@ SM_RETURN
SM_DECL(ansbinkp, (char *)"ansbinkp")
SM_STATES
ConnInit,
WaitConn,
WaitAddr,
IsPasswd,
@ -583,6 +599,7 @@ SM_STATES
PwdAck,
Opts
SM_NAMES
(char *)"ConnInit",
(char *)"WaitConn",
(char *)"WaitAddr",
(char *)"IsPasswd",
@ -590,12 +607,17 @@ SM_NAMES
(char *)"PwdAck",
(char *)"Opts"
SM_EDECL
char *p, *q, *pw;
int i, rc, bufl, cmd, dupe, we_have_pwd = FALSE, akas = 0;
fa_list **tmp, *tmpa;
faddr *fa;
char *p, *q, *pw;
int i, rc, cmd, dupe, we_have_pwd = FALSE, akas = 0;
unsigned long bufl;
fa_list **tmp, *tmpa;
faddr *fa;
SM_START(WaitConn)
SM_START(ConnInit)
SM_STATE(ConnInit)
SM_PROCEED(WaitConn)
SM_STATE(WaitConn)
@ -613,7 +635,14 @@ SM_STATE(WaitConn)
*/
char s[MD5_DIGEST_LEN*2+15]; /* max. length of opt string */
strcpy(s, "OPT ");
MD_toString(s+4, bp.MD_Challenge[0], bp.MD_Challenge+1);
#ifdef HAVE_ZLIB_H
if (bp.PLZflag == WeCan) {
strcpy(s + strlen(s), "PLZ ");
bp.PLZflag = WeWant;
Syslog('b', "PLZflag WeCan => WeWant");
}
#endif
MD_toString(s + strlen(s), bp.MD_Challenge[0], bp.MD_Challenge+1);
bp.CRAMflag = TRUE;
if ((rc = binkp_send_command(MM_NUL, "%s", s))) {
SM_ERROR;
@ -1639,9 +1668,13 @@ int binkp_banner(void)
/*
* Receive command frame
*/
int binkp_recv_command(char *buf, int *len, int *cmd)
int binkp_recv_command(char *buf, unsigned long *len, int *cmd)
{
int b0, b1;
int b0, b1;
#ifdef HAVE_ZLIB_H
int rc, zlen, plz = FALSE;
char *zbuf;
#endif
*len = *cmd = 0;
@ -1651,15 +1684,52 @@ int binkp_recv_command(char *buf, int *len, int *cmd)
if (b0 & 0x80)
*cmd = 1;
#ifdef HAVE_ZLIB_H
/*
* During session setup even if we are not yet in PLZ mode,
* we already accept zlib compressed packets. This assumes
* that there are no command messages longer then 16Kb.
*/
if ((b0 & 0x40) && (bp.PLZflag != No)) {
Syslog('b', "Binkp: binkp_recv_command() compressed block");
plz = TRUE;
}
#endif
b1 = GETCHAR(BINKP_TIMEOUT / 2);
if (tty_status)
goto to;
#ifdef HAVE_ZLIB_H
if (plz) {
*len = (b0 & 0x3f) << 8;
zbuf = calloc(*len +1, sizeof(char));
GET(zbuf, *len, BINKP_TIMEOUT / 2);
zlen = *len;
rc = uncompress(buf, len, zbuf, zlen);
free(zbuf);
if (rc == Z_OK) {
Syslog('b', "Binkp: uncompress size %d => %d", zlen, len);
} else {
Syslog('b', "Binkp: uncompress error %d", rc);
tty_status = STAT_UNCOMP;
}
buf[*len] = '\0';
} else {
*len = (b0 & 0x7f) << 8;
*len += b1;
GET(buf, *len, BINKP_TIMEOUT / 2);
buf[*len] = '\0';
}
#else
*len = (b0 & 0x7f) << 8;
*len += b1;
GET(buf, *len, BINKP_TIMEOUT / 2);
buf[*len] = '\0';
#endif
if (tty_status)
goto to;
@ -1713,15 +1783,39 @@ void parse_m_nul(char *msg)
} else if (strncmp(msg, "OPT ", 4) == 0) {
Syslog('+', "Options : %s", msg+4);
if (strstr(msg, (char *)"CRAM-MD5-") != NULL) { /* No SHA-1 support */
if (CFG.NoMD5) {
Syslog('+', "Binkp: Remote supports MD5, but it's turned off here");
p = msg;
q = strtok(p, " \n\r\0");
while ((q = strtok(NULL, " \r\n\0"))) {
Syslog('b', "Binkp: parsing opt \"%s\"", printable(q, 0));
if (strncmp(q, (char *)"CRAM-MD5-", 9) == 0) { /* No SHA-1 support */
if (CFG.NoMD5) {
Syslog('+', "Binkp: Remote supports MD5, but it's turned off here");
} else {
if (bp.MD_Challenge)
free(bp.MD_Challenge);
bp.MD_Challenge = MD_getChallenge(q, NULL);
}
#ifdef HAVE_ZLIB_H
} else if (strncmp(q, (char *)"PLZ", 3) == 0) {
Syslog('b', "Binkp: got PLZ, current state %s", opstate[bp.PLZflag]);
if (bp.PLZflag == WeCan) {
bp.PLZflag = TheyWant;
Syslog('b', "PLZflag WeCan => TheyWant");
binkp_send_command(MM_NUL,"OPT PLZ");
Syslog('b', "PLZflag TheyWant => Active");
bp.PLZflag = Active;
} else if (bp.PLZflag == WeWant) {
bp.PLZflag = Active;
Syslog('b', "PLZflag WeWant => Active");
} else {
Syslog('b', "PLZflag is %s and received PLZ option", opstate[bp.PLZflag]);
}
#endif
} else {
if (bp.MD_Challenge)
free(bp.MD_Challenge);
bp.MD_Challenge = MD_getChallenge(msg, NULL);
Syslog('b', "Binkp: opt not supported");
}
}
} else {
Syslog('+', "Binkp: M_NUL \"%s\"", msg);
}
@ -1739,6 +1833,11 @@ void parse_m_nul(char *msg)
int binkp_poll_frame(void)
{
int c, rc = 0, bcmd;
#ifdef HAVE_ZLIB_H
int plz = FALSE;
unsigned long zlen;
char *zbuf;
#endif
for (;;) {
if (bp.GotFrame) {
@ -1769,11 +1868,31 @@ int binkp_poll_frame(void)
default:bp.rxbuf[bp.rxlen-2] = c;
}
if (bp.rxlen == 1) {
bp.cmd = bp.header & 0x8000;
bp.cmd = bp.header & BINKP_CONTROL_BLOCK;
#ifdef HAVE_ZLIB_H
if (bp.PLZflag == Active) {
bp.blklen = bp.header & 0x3fff;
plz = bp.header & BINKP_PLZ_BLOCK;
} else {
bp.blklen = bp.header & 0x7fff;
}
#else
bp.blklen = bp.header & 0x7fff;
#endif
}
if ((bp.rxlen == (bp.blklen + 1) && (bp.rxlen >= 1))) {
bp.GotFrame = TRUE;
#ifdef HAVE_ZLIB_H
if (plz) {
Syslog('b', "Binkp: rcvd compressed block %d bytes", bp.rxlen -1);
zbuf = calloc(bp.rxlen, sizeof(char));
strncpy(zbuf, bp.rxbuf, bp.rxlen -1);
rc = uncompress(bp.rxbuf, &zlen, zbuf, bp.rxlen -1);
free(zbuf);
Syslog('b', "Binkp: uncompress rc=%d %d => %d", rc, bp.rxlen -1, zlen);
bp.rxlen = zlen +1;
}
#endif
bp.rxbuf[bp.rxlen-1] = '\0';
if (bp.cmd) {
bp.messages++;

View File

@ -1,5 +1,5 @@
#ifndef _BINKPNEW_H
#define _BINKPNEW_H
#ifndef _BINKP_H
#define _BINKP_H
/* $Id$ */
@ -9,13 +9,24 @@
binkp's frames:
+---------------------- 0=data block, 1=message(command)
| +---- data block size / msg's argument size
| +----- data block size / msg's argument size
| |
7 6543210 76543210
7 6543210 76543210
+-+-------+--------+--- ... ---+
| | HI LO | | -- data block / msg's argument
+-+-------+--------+--- ... ---+
binkp's frames in PLZ mode:
+---------------------- 0=data block, 1=message(command)
| +-------------------- 0=standard block, 1=zlib compressed block
| | +---- data block size / msg's argument size
| | |
7 6 543210 76543210
+-+-+------+--------+--- ... ---+
| | | HI LO | | -- data block / msg's argument
+-+-+------+--------+--- ... ---+
*/
@ -46,6 +57,7 @@
#define BINKP_DATA_BLOCK 0x0000
#define BINKP_CONTROL_BLOCK 0x8000
#define BINKP_PLZ_BLOCK 0x4000
typedef struct _binkp_frame {

View File

@ -4,7 +4,7 @@
* Purpose ...............: Fidonet mailer
*
*****************************************************************************
* Copyright (C) 1997-2003
* Copyright (C) 1997-2004
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@ -62,7 +62,8 @@ char *ttystat[]= {(char *)"Ok",
(char *)"TimeOut",
(char *)"EOF",
(char *)"Hangup",
(char *)"Empty"};
(char *)"Empty",
(char *)"UnCompress"};
int tty_resettimer(int tno);
void tty_resettimers(void);

View File

@ -33,6 +33,7 @@
#define STAT_EOFILE 3
#define STAT_HANGUP 4
#define STAT_EMPTY 5
#define STAT_UNCOMP 6
#define SUCCESS (STATUS == 0)
#define TERROR (-STAT_ERROR)