[Raw Msg Headers][Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

smtp TA over SSL not handling shutdown




I can re-create this one on demand.  The problem results in an smtp TA 
process being stuck in a tight loop, the read() = 0, meaning the TCP 
socket has closed.  But the TA doesn't appear to notice this.  I'm 
trying to understand the exit path in smtp_sync() when smtp_bread() 
returns -1 seems like voodoo.

Dont rely on my gdb output too much as I think compiler optimisation for 
the MIPS hardware results in some statements not appearing to get 
executed an others twice or out of order (-g -O2).  I'll try with just 
-g in a bit, but any pointers on what I should be looking out for?

One obvious thing I can see if that SSL_read() is used in place of 
read() but the return values for a closed/broken socket appear to be 
different.  But I would have expected the TA to have done something 
useful in reaction to an unexpected -1 error return in any case.


I'm thinking that some logic like this is needed in smtp_sync() but this 
hack isn't going to make that part of the code any easier to understand:

#ifdef HAVE_OPENSSL
/* SSL_read() had an error and it wasn't waiting for read or write */
if(len < 0 && SS->TLS.wantreadwrite == 0) {
    fprintf(logfp,"%s#\tSSL_read(): error occured\n", logtag());
    smtpclose(...);
    break;
}
#endif


read(6, "", 10451)                      = 0
time([1109833349])                      = 1109833349
write(3, "272501EFB-5157-8794#\tSSL_connect"..., 65) = 65
getpid()                                = 27250
getpid()                                = 27250
time([1109833349])                      = 1109833349
_newselect(7, [6], [], NULL, {0, 0})    = 1 (in [6], left {0, 0})
time(NULL)                              = 1109833349
getpid()                                = 27250
read(6, "", 10451)                      = 0
time([1109833349])                      = 1109833349
write(3, "272501EFB-5158-8794#\tSSL_connect"..., 65) = 65
getpid()                                = 27250
getpid()                                = 27250
time([1109833349])                      = 1109833349
_newselect(7, [6], [], NULL, {0, 0})    = 1 (in [6], left {0, 0})
time(NULL)                              = 1109833349
getpid()                                = 27250
read(6, "", 10451)                      = 0


smtp_sync (SS=0x7fff0bc0, r=2147408344, nonblocking=0) at smtp.c:4223
4223                  en = errno;
(gdb)
4224                  if (debug && logfp)
(gdb)
4227                  if (err < 0) {
(gdb)
4200                len = smtp_nbread(SS, buf, sizeof(buf));
(gdb) n
4204                if (SS->TLS.sslmode && SS->TLS.wantreadwrite > 0) waitwr = 1                              ;
(gdb) p len
$4 = -1
(gdb) n
4199                err = 0;
(gdb)
4204                if (SS->TLS.sslmode && SS->TLS.wantreadwrite > 0) waitwr = 1                              ;
(gdb)
4207                if (len < 0)
(gdb)
4208                  err = errno;
(gdb)
4210                if (!nonblocking && len < 0) {
(gdb)
4215                  int infd = SS->smtpfd;
(gdb)
4220                    err = -1; /* Write has failed, but we still drop here to read.. or something */
(gdb)
4218                    err = select_sleep(infd, when_timeout, waitwr);
(gdb)
4223                  en = errno;
(gdb) p err
$5 = 0
(gdb) n
4224                  if (debug && logfp)
(gdb) p en
$6 = 1
(gdb) n
4227                  if (err < 0) {
(gdb)
4200                len = smtp_nbread(SS, buf, sizeof(buf));
(gdb)
4204                if (SS->TLS.sslmode && SS->TLS.wantreadwrite > 0) waitwr = 1;
(gdb) p len
$7 = -1
(gdb) p SS->TLS.sslmode
$8 = 1
(gdb) p SS->TLS.wantreadwrite
$9 = 0
(gdb) n
4199                err = 0;
(gdb)
4204                if (SS->TLS.sslmode && SS->TLS.wantreadwrite > 0) waitwr = 1;
(gdb) n
4207                if (len < 0)
(gdb)
4208                  err = errno;
(gdb)
4210                if (!nonblocking && len < 0) {
(gdb) p err
$10 = 1
(gdb) p nonblocking
$11 = 0
(gdb) p len
$12 = -1
(gdb) n
4215                  int infd = SS->smtpfd;
(gdb)
4220                    err = -1; /* Write has failed, but we still drop here to read.. or something */
(gdb) p infd
$13 = 6
(gdb) n
4218                    err = select_sleep(infd, when_timeout, waitwr);





smtp_nbread (SS=0x1, buf=0x4226b496, spc=512) at smtptls.c:2036
2036            vlog = SS->verboselog;
(gdb) n
2039            if (SS->TLS.sslmode) {
(gdb)
2025    {
(gdb)
2036            vlog = SS->verboselog;
(gdb)
2027            int infd = SS->smtpfd;
(gdb)
2039            if (SS->TLS.sslmode) {
(gdb)
2040              r = SSL_read(SS->TLS.ssl, buf, spc);
(gdb)
2041              e = SSL_get_error(SS->TLS.ssl, r);
(gdb)
2040              r = SSL_read(SS->TLS.ssl, buf, spc);
(gdb)
2041              e = SSL_get_error(SS->TLS.ssl, r);
(gdb)
2042              switch (e) {
(gdb) p r
$25 = -1
(gdb) p e
$26 = 1
(gdb) n
2052                SS->TLS.wantreadwrite =  0;
(gdb)
2055              if (tls_loglevel >= 3) {
(gdb)
2071            errno = e;
(gdb) p r
$27 = -1




-- 
Darryl L. Miles


-
To unsubscribe from this list: send the line "unsubscribe zmailer" in
the body of a message to majordomo@nic.funet.fi