1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-27 10:07:40 +00:00

(trunk libT) fix connectivity error reported by Stargazer. Also, add more debug statements to track down errors like this in the future

This commit is contained in:
Charles Kerr 2008-12-24 02:50:08 +00:00
parent 87c1188866
commit 6f8e5352ab
2 changed files with 55 additions and 30 deletions

View file

@ -214,6 +214,7 @@ static void
event_read_cb( int fd, short event UNUSED, void * vio ) event_read_cb( int fd, short event UNUSED, void * vio )
{ {
int res; int res;
int e;
tr_peerIo * io = vio; tr_peerIo * io = vio;
/* Limit the input buffer to 256K, so it doesn't grow too large */ /* Limit the input buffer to 256K, so it doesn't grow too large */
@ -235,7 +236,9 @@ event_read_cb( int fd, short event UNUSED, void * vio )
return; return;
} }
errno = 0;
res = evbuffer_read( io->inbuf, fd, howmuch ); res = evbuffer_read( io->inbuf, fd, howmuch );
e = errno;
if( res > 0 ) if( res > 0 )
{ {
@ -251,13 +254,15 @@ event_read_cb( int fd, short event UNUSED, void * vio )
if( res == 0 ) /* EOF */ if( res == 0 ) /* EOF */
what |= EVBUFFER_EOF; what |= EVBUFFER_EOF;
else if( res == -1 ) { else if( res == -1 ) {
if( errno == EAGAIN || errno == EINTR ) { if( e == EAGAIN || e == EINTR ) {
tr_peerIoSetEnabled( io, dir, TRUE ); tr_peerIoSetEnabled( io, dir, TRUE );
return; return;
} }
what |= EVBUFFER_ERROR; what |= EVBUFFER_ERROR;
} }
dbgmsg( io, "event_read_cb got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, strerror( e ) );
if( io->gotError != NULL ) if( io->gotError != NULL )
io->gotError( io, what, io->userData ); io->gotError( io, what, io->userData );
} }
@ -268,13 +273,16 @@ tr_evbuffer_write( tr_peerIo * io, int fd, size_t howmuch )
{ {
struct evbuffer * buffer = io->outbuf; struct evbuffer * buffer = io->outbuf;
int n = MIN( EVBUFFER_LENGTH( buffer ), howmuch ); int n = MIN( EVBUFFER_LENGTH( buffer ), howmuch );
int e;
errno = 0;
#ifdef WIN32 #ifdef WIN32
n = send(fd, buffer->buffer, n, 0 ); n = send(fd, buffer->buffer, n, 0 );
#else #else
n = write(fd, buffer->buffer, n ); n = write(fd, buffer->buffer, n );
#endif #endif
dbgmsg( io, "wrote %d to peer (%s)", n, (n==-1?strerror(errno):"") ); e = errno;
dbgmsg( io, "wrote %d to peer (%s)", n, (n==-1?strerror(e):"") );
if( n == -1 ) if( n == -1 )
return -1; return -1;
@ -289,6 +297,7 @@ static void
event_write_cb( int fd, short event UNUSED, void * vio ) event_write_cb( int fd, short event UNUSED, void * vio )
{ {
int res = 0; int res = 0;
int e;
short what = EVBUFFER_WRITE; short what = EVBUFFER_WRITE;
tr_peerIo * io = vio; tr_peerIo * io = vio;
size_t howmuch; size_t howmuch;
@ -308,12 +317,15 @@ event_write_cb( int fd, short event UNUSED, void * vio )
return; return;
} }
errno = 0;
res = tr_evbuffer_write( io, fd, howmuch ); res = tr_evbuffer_write( io, fd, howmuch );
e = errno;
if (res == -1) { if (res == -1) {
#ifndef WIN32 #ifndef WIN32
/*todo. evbuffer uses WriteFile when WIN32 is set. WIN32 system calls do not /*todo. evbuffer uses WriteFile when WIN32 is set. WIN32 system calls do not
* *set errno. thus this error checking is not portable*/ * *set errno. thus this error checking is not portable*/
if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS) if (e == EAGAIN || e == EINTR || e == EINPROGRESS)
goto reschedule; goto reschedule;
/* error case */ /* error case */
what |= EVBUFFER_ERROR; what |= EVBUFFER_ERROR;
@ -341,6 +353,9 @@ event_write_cb( int fd, short event UNUSED, void * vio )
return; return;
error: error:
dbgmsg( io, "event_write_cb got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, strerror( e ) );
if( io->gotError != NULL ) if( io->gotError != NULL )
io->gotError( io, what, io->userData ); io->gotError( io, what, io->userData );
} }
@ -891,25 +906,30 @@ tr_peerIoGetAge( const tr_peerIo * io )
static int static int
tr_peerIoTryRead( tr_peerIo * io, size_t howmuch ) tr_peerIoTryRead( tr_peerIo * io, size_t howmuch )
{ {
int res; int res = 0;
assert( tr_isPeerIo( io ) ); assert( tr_isPeerIo( io ) );
howmuch = tr_bandwidthClamp( io->bandwidth, TR_DOWN, howmuch ); if(( howmuch = tr_bandwidthClamp( io->bandwidth, TR_DOWN, howmuch )))
res = howmuch ? evbuffer_read( io->inbuf, io->socket, howmuch ) : 0;
dbgmsg( io, "read %d from peer (%s)", res, (res==-1?strerror(errno):"") );
if( EVBUFFER_LENGTH( io->inbuf ) )
canReadWrapper( io );
if( ( res <= 0 ) && ( io->gotError ) && ( errno != EAGAIN ) && ( errno != EINTR ) && ( errno != EINPROGRESS ) )
{ {
short what = EVBUFFER_READ | EVBUFFER_ERROR; int e;
if( res == 0 ) errno = 0;
what |= EVBUFFER_EOF; res = evbuffer_read( io->inbuf, io->socket, howmuch );
io->gotError( io, what, io->userData ); e = errno;
dbgmsg( io, "read %d from peer (%s)", res, (res==-1?strerror(e):"") );
if( EVBUFFER_LENGTH( io->inbuf ) )
canReadWrapper( io );
if( ( res <= 0 ) && ( io->gotError ) && ( e != EAGAIN ) && ( e != EINTR ) && ( e != EINPROGRESS ) )
{
short what = EVBUFFER_READ | EVBUFFER_ERROR;
if( res == 0 )
what |= EVBUFFER_EOF;
dbgmsg( io, "tr_peerIoTryRead got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, strerror( e ) );
io->gotError( io, what, io->userData );
}
} }
return res; return res;
@ -922,16 +942,22 @@ tr_peerIoTryWrite( tr_peerIo * io, size_t howmuch )
assert( tr_isPeerIo( io ) ); assert( tr_isPeerIo( io ) );
howmuch = tr_bandwidthClamp( io->bandwidth, TR_UP, howmuch ); if(( howmuch = tr_bandwidthClamp( io->bandwidth, TR_UP, howmuch )))
{
int e;
errno = 0;
n = tr_evbuffer_write( io, io->socket, (int)howmuch );
e = errno;
n = tr_evbuffer_write( io, io->socket, (int)howmuch ); if( n > 0 )
didWriteWrapper( io, n );
if( n > 0 ) if( ( n < 0 ) && ( io->gotError ) && ( e != EPIPE ) && ( e != EAGAIN ) && ( e != EINTR ) && ( e != EINPROGRESS ) )
didWriteWrapper( io, n ); {
const short what = EVBUFFER_WRITE | EVBUFFER_ERROR;
if( ( n < 0 ) && ( io->gotError ) && ( errno != EPIPE ) && ( errno != EAGAIN ) && ( errno != EINTR ) && ( errno != EINPROGRESS ) ) { dbgmsg( io, "tr_peerIoTryWrite got an error. res is %d, what is %hd, errno is %d (%s)", n, what, e, strerror( e ) );
short what = EVBUFFER_WRITE | EVBUFFER_ERROR; io->gotError( io, what, io->userData );
io->gotError( io, what, io->userData ); }
} }
return n; return n;

View file

@ -913,8 +913,7 @@ addStrike( Torrent * t,
struct peer_atom * atom = getExistingAtom( t, &peer->addr ); struct peer_atom * atom = getExistingAtom( t, &peer->addr );
atom->myflags |= MYFLAG_BANNED; atom->myflags |= MYFLAG_BANNED;
peer->doPurge = 1; peer->doPurge = 1;
tordbg( t, "banning peer %s", tordbg( t, "banning peer %s", tr_peerIoAddrStr( &atom->addr, atom->port ) );
tr_peerIoAddrStr( &atom->addr, atom->port ) );
} }
} }
@ -1140,7 +1139,7 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt )
{ {
addStrike( t, peer ); addStrike( t, peer );
peer->doPurge = 1; peer->doPurge = 1;
tordbg( t, "setting doPurge because we got an EINVAL error" ); tordbg( t, "setting %s doPurge flag because we got an EINVAL error", tr_peerIoAddrStr( &peer->addr, peer->port ) );
} }
else if( ( e->err == ERANGE ) else if( ( e->err == ERANGE )
|| ( e->err == EMSGSIZE ) || ( e->err == EMSGSIZE )
@ -1148,7 +1147,7 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt )
{ {
/* some protocol error from the peer */ /* some protocol error from the peer */
peer->doPurge = 1; peer->doPurge = 1;
tordbg( t, "setting doPurge because we got an ERANGE, EMSGSIZE, or ENOTCONN error" ); tordbg( t, "setting %s doPurge flag because we got an ERANGE, EMSGSIZE, or ENOTCONN error", tr_peerIoAddrStr( &peer->addr, peer->port ) );
} }
else /* a local error, such as an IO error */ else /* a local error, such as an IO error */
{ {