From 4de5a40af8cfc00866c7997ecf5b2971877f6b04 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Wed, 17 Mar 2010 22:52:36 +0000 Subject: [PATCH] * CtdlClientGetLine(): we don't support Error while SSL I/O; remove it. * client_readline_sslbuffer() put in Pos from the outside * client_readline_sslbuffer() rewrite contents with StrBufTCP_read_buffered_line_fast() as sample --- citadel/modules/crypto/serv_crypto.c | 118 +++++++++++++++++---------- citadel/modules/crypto/serv_crypto.h | 2 +- citadel/sysdep.c | 8 +- 3 files changed, 82 insertions(+), 46 deletions(-) diff --git a/citadel/modules/crypto/serv_crypto.c b/citadel/modules/crypto/serv_crypto.c index 5ba6ffc56..7e4701537 100644 --- a/citadel/modules/crypto/serv_crypto.c +++ b/citadel/modules/crypto/serv_crypto.c @@ -467,56 +467,92 @@ int client_read_sslbuffer(StrBuf *buf, int timeout) return (0); } -int client_readline_sslbuffer(StrBuf *Target, StrBuf *Buffer, int timeout) +int client_readline_sslbuffer(StrBuf *Line, StrBuf *IOBuf, const char **Pos, int timeout) { - int ntries = 0; - const char *pch, *pchs; - int rlen, len, retval = 0; CitContext *CCC = CC; + const char *pos = NULL; + const char *pLF; + int len, rlen, retlen; + int nSuccessLess = 0; + const char *pch = NULL; + + retlen = 0; + if ((Line == NULL) || + (Pos == NULL) || + (IOBuf == NULL)) + { + if (Pos != NULL) + *Pos = NULL; +// *Error = ErrRBLF_PreConditionFailed; + return -1; + } + + pos = *Pos; + if ((StrLength(IOBuf) > 0) && + (pos != NULL) && + (pos < ChrPtr(IOBuf) + StrLength(IOBuf))) + { + pch = pos; + pch = strchr(pch, '\n'); + + if (pch == NULL) { + StrBufAppendBufPlain(Line, pos, + StrLength(IOBuf) - (pos - ChrPtr(IOBuf)), 0); + FlushStrBuf(IOBuf); + pos = *Pos = NULL; + } + else { + int n = 0; + if ((pch > ChrPtr(IOBuf)) && + (*(pch - 1) == '\r')) { + n = 1; + } + StrBufAppendBufPlain(Line, pos, + (pch - pos - n), 0); - if (StrLength(Target) > 0) { - pchs = ChrPtr(Buffer); - pch = strchr(pchs, '\n'); - if (pch != NULL) { - rlen = 0; - len = pch - pchs; - if (len > 0 && (*(pch - 1) == '\r') ) - rlen ++; - StrBufSub(Target, Buffer, 0, len - rlen); - StrBufCutLeft(Buffer, len + 1); - return len - rlen; + if (StrLength(IOBuf) <= (pch - ChrPtr(IOBuf) + 1)) { + FlushStrBuf(IOBuf); + pos = *Pos = NULL; + } + else + *Pos = pch + 1; + return StrLength(Line); } } - - while ((retval == 0) && (CCC->ssl != NULL)) { - pch = NULL; - pchs = ChrPtr(Buffer); - if (*pchs != '\0') - pch = strchr(pchs, '\n'); - if (pch == NULL) { - retval = client_read_sslbuffer(Buffer, timeout); - pchs = ChrPtr(Buffer); - pch = strchr(pchs, '\n'); + + pLF = NULL; + while ((nSuccessLess < timeout) && + (pLF == NULL) && + (CCC->ssl != NULL)) { + + rlen = client_read_sslbuffer(IOBuf, timeout); + if (rlen < 1) { +// *Error = strerror(errno); +// close(*fd); +// *fd = -1; + return -1; } - if (retval == 0) { - sleep(1); - ntries ++; + else if (rlen > 0) { + pLF = strchr(ChrPtr(IOBuf), '\n'); } - if (ntries > 10) - return 0; } - if ((retval > 0) && (pch != NULL)) { - rlen = 0; - len = pch - pchs; - if (len > 0 && (*(pch - 1) == '\r') ) - rlen ++; - StrBufSub(Target, Buffer, 0, len - rlen); - StrBufCutLeft(Buffer, len + 1); - return len - rlen; - + *Pos = NULL; + if (pLF != NULL) { + pos = ChrPtr(IOBuf); + len = pLF - pos; + if (len > 0 && (*(pLF - 1) == '\r') ) + len --; + StrBufAppendBufPlain(Line, pos, len, 0); + if (pLF + 1 >= ChrPtr(IOBuf) + StrLength(IOBuf)) + { + FlushStrBuf(IOBuf); + } + else + *Pos = pLF + 1; + return StrLength(Line); } - else - return -1; +// *Error = ErrRBLF_NotEnoughSentFromServer; + return -1; } diff --git a/citadel/modules/crypto/serv_crypto.h b/citadel/modules/crypto/serv_crypto.h index 40c5d4807..c7b033794 100644 --- a/citadel/modules/crypto/serv_crypto.h +++ b/citadel/modules/crypto/serv_crypto.h @@ -16,7 +16,7 @@ void destruct_ssl(void); void init_ssl(void); void client_write_ssl (const char *buf, int nbytes); int client_read_sslbuffer(StrBuf *buf, int timeout); -int client_readline_sslbuffer(StrBuf *Target, StrBuf *Buffer, int timeout); +int client_readline_sslbuffer(StrBuf *Target, StrBuf *Buffer, const char **Pos, int timeout); int client_read_sslblob(StrBuf *Target, long want_len, int timeout); void cmd_stls(char *params); void cmd_gtls(char *params); diff --git a/citadel/sysdep.c b/citadel/sysdep.c index f8a320709..36e10e804 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -694,6 +694,7 @@ int CtdlClientGetLine(StrBuf *Target) #endif rc = client_readline_sslbuffer(Target, CCC->ReadBuf, + &CCC->Pos, 1); #ifdef BIGBAD_IODBG pch = ChrPtr(CCC->ReadBuf); @@ -713,11 +714,10 @@ int CtdlClientGetLine(StrBuf *Target) StrLength(Target), ChrPtr(Target)); fclose(fd); - if ((rc < 0) && (Error != NULL)) + if (rc < 0) CtdlLogPrintf(CTDL_CRIT, - "%s failed: %s\n", - __FUNCTION__, - Error); + "%s failed\n", + __FUNCTION__); #endif return rc; } -- 2.30.2