Commit e579d2d9 authored by Tollef Fog Heen's avatar Tollef Fog Heen

Merge r3866: Handle telnet options

Add minimal facility for dealing with TELNET option negotiation
in a way that telnet clients don't get confused about:

Return WONT on to all DO or DONT and ignore everything else.



git-svn-id: http://www.varnish-cache.org/svn/branches/2.0@3981 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent e870e5e4
......@@ -372,6 +372,10 @@ mgt_cli_setup(int fdi, int fdo, int verbose, const char *ident)
cp->cli->sb = vsb_newauto();
XXXAN(cp->cli->sb);
/* Deal with TELNET options */
if (cp->fdi != 0)
VLU_SetTelnet(cp->vlu, cp->fdo);
cp->ev = calloc(sizeof *cp->ev, 1);
cp->ev->name = cp->name;
cp->ev->fd = fdi;
......
......@@ -37,5 +37,6 @@ struct vlu *VLU_New(void *priv, vlu_f *func, unsigned bufsize);
int VLU_Fd(int fd, struct vlu *l);
int VLU_File(FILE *f, struct vlu *l);
void VLU_Destroy(struct vlu *l);
void VLU_SetTelnet(struct vlu *l, int fd);
#endif
......@@ -46,6 +46,7 @@ struct vlu {
unsigned bufl;
unsigned bufp;
void *priv;
int telnet;
vlu_f *func;
};
......@@ -66,10 +67,19 @@ VLU_New(void *priv, vlu_f *func, unsigned bufsize)
FREE_OBJ(l);
l = NULL;
}
l->telnet = -1;
}
return (l);
}
void
VLU_SetTelnet(struct vlu *l, int fd)
{
CHECK_OBJ_NOTNULL(l, LINEUP_MAGIC);
assert(fd >= 0);
l->telnet = fd;
}
void
VLU_Destroy(struct vlu *l)
{
......@@ -79,6 +89,51 @@ VLU_Destroy(struct vlu *l)
FREE_OBJ(l);
}
static int
vlu_dotelnet(struct vlu *l, char *p)
{
char *e;
char tno[3];
int i;
e = l->buf + l->bufp;
assert(p >= l->buf && p < e);
assert(*p == (char)255);
/* We need at least two characters */
if (p == e - 1)
return (1);
/* And three for will/wont/do/dont */
if (p[1] >= (char)251 && p[1] <= (char)254 && p == e - 2)
return (1);
switch (p[1]) {
case (char)251: /* WILL */
case (char)252: /* WONT */
/* Ignore these */
i = 3;
break;
case (char)253: /* DO */
case (char)254: /* DONT */
/* Return WONT for these */
memcpy(tno, p, 3);
tno[1] = (char)252;
write(l->telnet, tno, 3);
i = 3;
break;
default:
/* Ignore the rest */
/* XXX: only p[1] >= 240 ? */
i = 2;
}
/* Remove telnet sequence from buffer */
memmove(p, p + i, 1 + e - (p + i));
l->bufp -= i;
return (0);
}
static int
LineUpProcess(struct vlu *l)
{
......@@ -88,9 +143,13 @@ LineUpProcess(struct vlu *l)
l->buf[l->bufp] = '\0';
for (p = l->buf; *p != '\0'; p = q) {
/* Find first CR or NL */
for (q = p; *q != '\0'; q++)
for (q = p; *q != '\0'; q++) {
while (l->telnet >= 0 && *q == (char)255)
if (vlu_dotelnet(l, q))
return (0);
if (*q == '\n' || *q == '\r')
break;
}
if (*q == '\0')
break;
*q++ = '\0';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment