mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 16:18:48 -05:00
Improved telnet support by drastically reducing the number of write
callbacks needed to pass a buffer to the user. Instead one per byte it is now as little as one per segment.
This commit is contained in:
parent
70f10f1ac9
commit
33f7ac06c3
5
CHANGES
5
CHANGES
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
Dan F (6 Nov 2007)
|
||||||
|
- Improved telnet support by drastically reducing the number of write
|
||||||
|
callbacks needed to pass a buffer to the user. Instead one per byte it
|
||||||
|
is now as little as one per segment.
|
||||||
|
|
||||||
Yang Tse (6 Nov 2007)
|
Yang Tse (6 Nov 2007)
|
||||||
- Bug report #1824894 (http://curl.haxx.se/bug/view.cgi?id=1824894) pointed
|
- Bug report #1824894 (http://curl.haxx.se/bug/view.cgi?id=1824894) pointed
|
||||||
out a problem in curl.h when building C++ apps with MSVC. To fix it, the
|
out a problem in curl.h when building C++ apps with MSVC. To fix it, the
|
||||||
|
63
lib/telnet.c
63
lib/telnet.c
@ -106,7 +106,7 @@ static CURLcode check_wsock2 ( struct SessionHandle *data );
|
|||||||
|
|
||||||
static
|
static
|
||||||
void telrcv(struct connectdata *,
|
void telrcv(struct connectdata *,
|
||||||
unsigned char *inbuf, /* Data received from socket */
|
const unsigned char *inbuf, /* Data received from socket */
|
||||||
ssize_t count); /* Number of bytes received */
|
ssize_t count); /* Number of bytes received */
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||||
@ -949,104 +949,119 @@ static void suboption(struct connectdata *conn)
|
|||||||
|
|
||||||
static
|
static
|
||||||
void telrcv(struct connectdata *conn,
|
void telrcv(struct connectdata *conn,
|
||||||
unsigned char *inbuf, /* Data received from socket */
|
const unsigned char *inbuf, /* Data received from socket */
|
||||||
ssize_t count) /* Number of bytes received */
|
ssize_t count) /* Number of bytes received */
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
int in = 0;
|
int in = 0;
|
||||||
|
int startwrite=-1;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct TELNET *tn = (struct TELNET *)data->reqdata.proto.telnet;
|
struct TELNET *tn = (struct TELNET *)data->reqdata.proto.telnet;
|
||||||
|
|
||||||
|
#define startskipping() \
|
||||||
|
if (startwrite >= 0) \
|
||||||
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&inbuf[startwrite], in-startwrite); \
|
||||||
|
startwrite = -1
|
||||||
|
|
||||||
|
#define writebyte() \
|
||||||
|
if (startwrite < 0) \
|
||||||
|
startwrite = in
|
||||||
|
|
||||||
|
#define bufferflush() startskipping()
|
||||||
|
|
||||||
while(count--)
|
while(count--)
|
||||||
{
|
{
|
||||||
c = inbuf[in++];
|
c = inbuf[in];
|
||||||
|
|
||||||
|
/*infof(data,"In rcv state %d char %d\n", tn->telrcv_state, c);*/
|
||||||
switch (tn->telrcv_state)
|
switch (tn->telrcv_state)
|
||||||
{
|
{
|
||||||
case CURL_TS_CR:
|
case CURL_TS_CR:
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
if(c == '\0')
|
if(c == '\0')
|
||||||
{
|
{
|
||||||
|
startskipping();
|
||||||
break; /* Ignore \0 after CR */
|
break; /* Ignore \0 after CR */
|
||||||
}
|
}
|
||||||
|
writebyte();
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
|
break;
|
||||||
continue;
|
|
||||||
|
|
||||||
case CURL_TS_DATA:
|
case CURL_TS_DATA:
|
||||||
if(c == CURL_IAC)
|
if(c == CURL_IAC)
|
||||||
{
|
{
|
||||||
tn->telrcv_state = CURL_TS_IAC;
|
tn->telrcv_state = CURL_TS_IAC;
|
||||||
|
startskipping();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(c == '\r')
|
else if(c == '\r')
|
||||||
{
|
{
|
||||||
tn->telrcv_state = CURL_TS_CR;
|
tn->telrcv_state = CURL_TS_CR;
|
||||||
}
|
}
|
||||||
|
writebyte();
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
|
break;
|
||||||
continue;
|
|
||||||
|
|
||||||
case CURL_TS_IAC:
|
case CURL_TS_IAC:
|
||||||
process_iac:
|
process_iac:
|
||||||
|
DEBUGASSERT(startwrite < 0);
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case CURL_WILL:
|
case CURL_WILL:
|
||||||
tn->telrcv_state = CURL_TS_WILL;
|
tn->telrcv_state = CURL_TS_WILL;
|
||||||
continue;
|
break;
|
||||||
case CURL_WONT:
|
case CURL_WONT:
|
||||||
tn->telrcv_state = CURL_TS_WONT;
|
tn->telrcv_state = CURL_TS_WONT;
|
||||||
continue;
|
break;
|
||||||
case CURL_DO:
|
case CURL_DO:
|
||||||
tn->telrcv_state = CURL_TS_DO;
|
tn->telrcv_state = CURL_TS_DO;
|
||||||
continue;
|
break;
|
||||||
case CURL_DONT:
|
case CURL_DONT:
|
||||||
tn->telrcv_state = CURL_TS_DONT;
|
tn->telrcv_state = CURL_TS_DONT;
|
||||||
continue;
|
break;
|
||||||
case CURL_SB:
|
case CURL_SB:
|
||||||
CURL_SB_CLEAR(tn);
|
CURL_SB_CLEAR(tn);
|
||||||
tn->telrcv_state = CURL_TS_SB;
|
tn->telrcv_state = CURL_TS_SB;
|
||||||
continue;
|
break;
|
||||||
case CURL_IAC:
|
case CURL_IAC:
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
|
writebyte();
|
||||||
break;
|
break;
|
||||||
case CURL_DM:
|
case CURL_DM:
|
||||||
case CURL_NOP:
|
case CURL_NOP:
|
||||||
case CURL_GA:
|
case CURL_GA:
|
||||||
default:
|
default:
|
||||||
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
printoption(data, "RCVD", CURL_IAC, c);
|
printoption(data, "RCVD", CURL_IAC, c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
break;
|
||||||
continue;
|
|
||||||
|
|
||||||
case CURL_TS_WILL:
|
case CURL_TS_WILL:
|
||||||
printoption(data, "RCVD", CURL_WILL, c);
|
printoption(data, "RCVD", CURL_WILL, c);
|
||||||
tn->please_negotiate = 1;
|
tn->please_negotiate = 1;
|
||||||
rec_will(conn, c);
|
rec_will(conn, c);
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case CURL_TS_WONT:
|
case CURL_TS_WONT:
|
||||||
printoption(data, "RCVD", CURL_WONT, c);
|
printoption(data, "RCVD", CURL_WONT, c);
|
||||||
tn->please_negotiate = 1;
|
tn->please_negotiate = 1;
|
||||||
rec_wont(conn, c);
|
rec_wont(conn, c);
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case CURL_TS_DO:
|
case CURL_TS_DO:
|
||||||
printoption(data, "RCVD", CURL_DO, c);
|
printoption(data, "RCVD", CURL_DO, c);
|
||||||
tn->please_negotiate = 1;
|
tn->please_negotiate = 1;
|
||||||
rec_do(conn, c);
|
rec_do(conn, c);
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case CURL_TS_DONT:
|
case CURL_TS_DONT:
|
||||||
printoption(data, "RCVD", CURL_DONT, c);
|
printoption(data, "RCVD", CURL_DONT, c);
|
||||||
tn->please_negotiate = 1;
|
tn->please_negotiate = 1;
|
||||||
rec_dont(conn, c);
|
rec_dont(conn, c);
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case CURL_TS_SB:
|
case CURL_TS_SB:
|
||||||
if(c == CURL_IAC)
|
if(c == CURL_IAC)
|
||||||
@ -1057,7 +1072,7 @@ void telrcv(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURL_SB_ACCUM(tn,c);
|
CURL_SB_ACCUM(tn,c);
|
||||||
}
|
}
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case CURL_TS_SE:
|
case CURL_TS_SE:
|
||||||
if(c != CURL_SE)
|
if(c != CURL_SE)
|
||||||
@ -1097,7 +1112,9 @@ void telrcv(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
++in;
|
||||||
}
|
}
|
||||||
|
bufferflush();
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode Curl_telnet_done(struct connectdata *conn,
|
static CURLcode Curl_telnet_done(struct connectdata *conn,
|
||||||
@ -1143,7 +1160,7 @@ static CURLcode Curl_telnet(struct connectdata *conn, bool *done)
|
|||||||
char *buf = data->state.buffer;
|
char *buf = data->state.buffer;
|
||||||
struct TELNET *tn;
|
struct TELNET *tn;
|
||||||
|
|
||||||
*done = TRUE; /* uncontionally */
|
*done = TRUE; /* unconditionally */
|
||||||
|
|
||||||
code = init_telnet(conn);
|
code = init_telnet(conn);
|
||||||
if(code)
|
if(code)
|
||||||
|
Loading…
Reference in New Issue
Block a user