1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-10 06:02:57 +00:00

Use sockerrno and tr_net_strerror for most of network-related errors

This ensures proper network errors formatting on Windows.

Also, disable IP_TOS socket option modification attempts on Windows
since it's not supported there and is considered deprecated: "Do not
use. Type of Service (TOS) settings should only be set using the
Quality of Service API" (c) MSDN. Using QoS API is a subject for
separate commit(s).
This commit is contained in:
Mike Gelfand 2015-07-01 00:54:41 +00:00
parent 1a885dcb17
commit 79195614b2
5 changed files with 43 additions and 26 deletions

View file

@ -518,7 +518,11 @@ tr_fdSocketCreate (tr_session * session,
if (gFd->peerCount < session->peerLimit)
if ((s = socket (domain, type, 0)) == TR_BAD_SOCKET)
if (sockerrno != EAFNOSUPPORT)
tr_logAddError (_("Couldn't create socket: %s"), tr_strerror (sockerrno));
{
char err_buf[512];
tr_logAddError (_("Couldn't create socket: %s"),
tr_net_strerror (err_buf, sizeof (err_buf), sockerrno));
}
if (s != TR_BAD_SOCKET)
++gFd->peerCount;

View file

@ -229,6 +229,7 @@ tr_logAddMessage (const char * file,
va_end (ap);
OutputDebugStringA (buf);
OutputDebugStringA (TR_NATIVE_EOL_STR);
if (*buf)
{

View file

@ -76,6 +76,8 @@ tr_net_strerror (char * buf, size_t buflen, int err)
*buf = '\0';
#ifdef _WIN32
FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, buflen, NULL);
while (len > 0 && buf[len - 1] >= '\0' && buf[len - 1] <= ' ')
buf[--len] = '\0';
#else
tr_strlcpy (buf, tr_strerror (err), buflen);
#endif
@ -148,15 +150,17 @@ void
tr_netSetTOS (tr_socket_t s,
int tos)
{
#ifdef IP_TOS
if (setsockopt (s, IPPROTO_IP, IP_TOS, (const void *) &tos, sizeof (tos)) != -1)
return;
#if defined (IP_TOS) && !defined (_WIN32)
if (setsockopt (s, IPPROTO_IP, IP_TOS, (const void *) &tos, sizeof (tos)) == -1)
{
char err_buf[512];
tr_logAddNamedInfo ("Net", "Can't set TOS '%d': %s", tos,
tr_net_strerror (err_buf, sizeof (err_buf), sockerrno));
}
#else
(void) s;
errno = ENOSYS;
(void) tos;
#endif
tr_logAddNamedInfo ("Net", "Can't set TOS '%d': %s", tos, tr_strerror (errno));
}
void
@ -165,16 +169,16 @@ tr_netSetCongestionControl (tr_socket_t s,
{
#ifdef TCP_CONGESTION
if (setsockopt (s, IPPROTO_TCP, TCP_CONGESTION,
(const void *) algorithm, strlen (algorithm) + 1) != -1)
return;
(const void *) algorithm, strlen (algorithm) + 1) == -1)
{
char err_buf[512];
tr_logAddNamedInfo ("Net", "Can't set congestion control algorithm '%s': %s",
algorithm, tr_net_strerror (err_buf, sizeof (err_buf), sockerrno));
}
#else
(void) s;
errno = ENOSYS;
(void) algorithm;
#endif
tr_logAddNamedInfo ("Net", "Can't set congestion control algorithm '%s': %s",
algorithm, tr_strerror (errno));
}
bool
@ -246,6 +250,7 @@ tr_netOpenPeerSocket (tr_session * session,
const tr_address * source_addr;
socklen_t sourcelen;
struct sockaddr_storage source_sock;
char err_buf[512];
assert (tr_address_is_valid (addr));
@ -260,7 +265,8 @@ tr_netOpenPeerSocket (tr_session * session,
if (clientIsSeed) {
int n = 8192;
if (setsockopt (s, SOL_SOCKET, SO_RCVBUF, (const void *) &n, sizeof (n)))
tr_logAddInfo ("Unable to set SO_RCVBUF on socket %"TR_PRI_SOCK": %s", s, tr_strerror (sockerrno));
tr_logAddInfo ("Unable to set SO_RCVBUF on socket %"TR_PRI_SOCK": %s", s,
tr_net_strerror (err_buf, sizeof (err_buf), sockerrno));
}
if (evutil_make_socket_nonblocking (s) < 0) {
@ -277,7 +283,8 @@ tr_netOpenPeerSocket (tr_session * session,
if (bind (s, (struct sockaddr *) &source_sock, sourcelen))
{
tr_logAddError (_("Couldn't set source address %s on %"TR_PRI_SOCK": %s"),
tr_address_to_string (source_addr), s, tr_strerror (errno));
tr_address_to_string (source_addr), s,
tr_net_strerror (err_buf, sizeof (err_buf), sockerrno));
tr_netClose (session, s);
return TR_BAD_SOCKET; /* -errno */
}
@ -291,11 +298,12 @@ tr_netOpenPeerSocket (tr_session * session,
{
int tmperrno;
tmperrno = sockerrno;
if ((tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH)
|| addr->type == TR_AF_INET)
if ((tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH) || addr->type == TR_AF_INET)
{
tr_logAddError (_("Couldn't connect socket %"TR_PRI_SOCK" to %s, port %d (errno %d - %s)"),
s, tr_address_to_string (addr), (int)ntohs (port), tmperrno,
tr_strerror (tmperrno));
tr_net_strerror (err_buf, sizeof (err_buf), tmperrno));
}
tr_netClose (session, s);
s = TR_BAD_SOCKET; /* -tmperrno */
}
@ -371,6 +379,7 @@ tr_netBindTCPImpl (const tr_address * addr,
{
const char * fmt;
const char * hint;
char err_buf[512];
if (err == EADDRINUSE)
hint = _("Is another copy of Transmission already running?");
@ -382,7 +391,8 @@ tr_netBindTCPImpl (const tr_address * addr,
else
fmt = _("Couldn't bind port %d on %s: %s (%s)");
tr_logAddError (fmt, port, tr_address_to_string (addr), tr_strerror (err), hint);
tr_logAddError (fmt, port, tr_address_to_string (addr),
tr_net_strerror (err_buf, sizeof (err_buf), err), hint);
}
tr_netCloseSocket (fd);
*errOut = err;

View file

@ -1255,24 +1255,25 @@ tr_peerIoTryRead (tr_peerIo * io, size_t howmuch)
else /* tcp peer connection */
{
int e;
char err_buf[512];
EVUTIL_SET_SOCKET_ERROR (0);
res = evbuffer_read (io->inbuf, io->socket, (int)howmuch);
e = EVUTIL_SOCKET_ERROR ();
dbgmsg (io, "read %d from peer (%s)", res, (res==-1?tr_strerror (e):""));
dbgmsg (io, "read %d from peer (%s)", res,
(res==-1?tr_net_strerror (err_buf, sizeof (err_buf), e):""));
if (evbuffer_get_length (io->inbuf))
canReadWrapper (io);
if ((res <= 0) && (io->gotError) && (e != EAGAIN) && (e != EINTR) && (e != EINPROGRESS))
{
char errstr[512];
short what = BEV_EVENT_READING | BEV_EVENT_ERROR;
if (res == 0)
what |= BEV_EVENT_EOF;
dbgmsg (io, "tr_peerIoTryRead got an error. res is %d, what is %hd, errno is %d (%s)",
res, what, e, tr_net_strerror (errstr, sizeof (errstr), e));
res, what, e, tr_net_strerror (err_buf, sizeof (err_buf), e));
io->gotError (io, what, io->userData);
}
}

View file

@ -56,18 +56,19 @@ set_socket_buffers (tr_socket_t fd,
{
int size, rbuf, sbuf, rc;
socklen_t rbuf_len = sizeof (rbuf), sbuf_len = sizeof (sbuf);
char err_buf[512];
size = large ? RECV_BUFFER_SIZE : SMALL_BUFFER_SIZE;
rc = setsockopt (fd, SOL_SOCKET, SO_RCVBUF, (const void *) &size, sizeof (size));
if (rc < 0)
tr_logAddNamedError ("UDP", "Failed to set receive buffer: %s",
tr_strerror (errno));
tr_net_strerror (err_buf, sizeof (err_buf), sockerrno));
size = large ? SEND_BUFFER_SIZE : SMALL_BUFFER_SIZE;
rc = setsockopt (fd, SOL_SOCKET, SO_SNDBUF, (const void *) &size, sizeof (size));
if (rc < 0)
tr_logAddNamedError ("UDP", "Failed to set send buffer: %s",
tr_strerror (errno));
tr_net_strerror (err_buf, sizeof (err_buf), sockerrno));
if (large) {
rc = getsockopt (fd, SOL_SOCKET, SO_RCVBUF, (void *) &rbuf, &rbuf_len);