| 42 | "SOCKS4 Proxy handshake aborted by server" |
| 43 | "SSL fatal error" |
| 44 | "Reverse connect failure" |
+ | 45 | "Poller reported POLLERR" |
+ | 46 | "ECONNREFUSED returned by OS" |
+ | 47 | "ECONNRESET returned by OS" |
+ | 48 | "ENETUNREACH returned by OS" |
+ | 49 | "ENOMEM returned by OS" |
+ | 50 | "EBADF returned by OS" |
+ | 51 | "EFAULT returned by OS" |
+ | 52 | "EINVAL returned by OS" |
+ | 53 | "ENCONN returned by OS" |
+ | 54 | "ENSOCK returned by OS" |
+ | 55 | "ENOBUFS returned by OS" |
+ | 56 | "EPIPE returned by OS" |
+----+---------------------------------------------------------------------------+
fc_fackets : integer
CO_ER_SSL_FATAL, /* SSL fatal error during a SSL_read or SSL_write */
CO_ER_REVERSE, /* Error during reverse connect */
+
+ CO_ER_POLLERR, /* we only noticed POLLERR */
+ CO_ER_EREFUSED, /* ECONNREFUSED returned to recv/send */
+ CO_ER_ERESET, /* ECONNRESET returned to recv/send */
+ CO_ER_EUNREACH, /* ENETUNREACH returned to recv/send */
+ CO_ER_ENOMEM, /* ENOMEM returned to recv/send */
+ CO_ER_EBADF, /* EBADF returned to recv/send (serious bug) */
+ CO_ER_EFAULT, /* EFAULT returned to recv/send (serious bug) */
+ CO_ER_EINVAL, /* EINVAL returned to recv/send (serious bug) */
+ CO_ER_ENCONN, /* ENCONN returned to recv/send */
+ CO_ER_ENSOCK, /* ENSOCK returned to recv/send */
+ CO_ER_ENOBUFS, /* ENOBUFS returned to send */
+ CO_ER_EPIPE, /* EPIPE returned to send */
};
/* error return codes for accept_conn() */
struct connection *conn_new(void *target);
void conn_free(struct connection *conn);
void conn_release(struct connection *conn);
+void conn_set_errno(struct connection *conn, int err);
struct conn_hash_node *conn_alloc_hash_node(struct connection *conn);
struct sockaddr_storage *sockaddr_alloc(struct sockaddr_storage **sap, const struct sockaddr_storage *orig, socklen_t len);
void sockaddr_free(struct sockaddr_storage **sap);
extern struct idle_conns idle_conns[MAX_THREADS];
+/* set conn->err_code to any CO_ER_* code if it was not set yet, otherwise
+ * does nothing.
+ */
+static inline void conn_set_errcode(struct connection *conn, int err_code)
+{
+ if (!conn->err_code)
+ conn->err_code = err_code;
+}
+
/* returns true if the transport layer is ready */
static inline int conn_xprt_ready(const struct connection *conn)
{
case CO_ER_SSL_FATAL: return "SSL fatal error";
case CO_ER_REVERSE: return "Reverse connect failure";
+
+ case CO_ER_POLLERR: return "Poller reported POLLERR";
+ case CO_ER_EREFUSED: return "ECONNREFUSED returned by OS";
+ case CO_ER_ERESET: return "ECONNRESET returned by OS";
+ case CO_ER_EUNREACH: return "ENETUNREACH returned by OS";
+ case CO_ER_ENOMEM: return "ENOMEM returned by OS";
+ case CO_ER_EBADF: return "EBADF returned by OS";
+ case CO_ER_EFAULT: return "EFAULT returned by OS";
+ case CO_ER_EINVAL: return "EINVAL returned by OS";
+ case CO_ER_ENCONN: return "ENCONN returned by OS";
+ case CO_ER_ENSOCK: return "ENSOCK returned by OS";
+ case CO_ER_ENOBUFS: return "ENOBUFS returned by OS";
+ case CO_ER_EPIPE: return "EPIPE returned by OS";
}
return NULL;
}
+/* Try to set conn->err_code to a meaningful value based on the errno value
+ * passed in <err>. Values of errno are meant to be set on return from recv/
+ * send mostly, so not all of them are handled. Any existing err_code is
+ * preserved.
+ */
+void conn_set_errno(struct connection *conn, int err)
+{
+ uchar code = 0;
+
+ if (conn->err_code)
+ return;
+
+ switch (err) {
+ case ECONNREFUSED: code = CO_ER_EREFUSED; break;
+ case ECONNRESET: code = CO_ER_ERESET; break;
+ case EHOSTUNREACH: code = CO_ER_EUNREACH; break;
+ case ENETUNREACH: code = CO_ER_EUNREACH; break;
+ case ENOMEM: code = CO_ER_ENOMEM; break;
+ case EBADF: code = CO_ER_EBADF; break;
+ case EFAULT: code = CO_ER_EFAULT; break;
+ case EINVAL: code = CO_ER_EINVAL; break;
+ case ENOTCONN: code = CO_ER_ENCONN; break;
+ case ENOTSOCK: code = CO_ER_ENSOCK; break;
+ case ENOBUFS: code = CO_ER_ENOBUFS; break;
+ case EPIPE: code = CO_ER_EPIPE; break;
+ default: code = CO_ER_SOCK_ERR; break;
+ }
+
+ conn->err_code = code;
+}
+
/* Send a message over an established connection. It makes use of send() and
* returns the same return code and errno. If the socket layer is not ready yet
* then -1 is returned and ENOTSOCK is set into errno. If the fd is not marked