struct event_base *base;
struct evdns_base *dns_base;
+
+ /* Saved conn_addr, to extract IP address from it.
+ *
+ * Because some servers may reset/close connection without waiting clients,
+ * in that case we can't extract IP address even in close_cb.
+ * So we need to save it, just after we connected to remote server. */
+ struct sockaddr_storage *conn_address;
};
/* A callback for an http server */
if (evcon->address != NULL)
mm_free(evcon->address);
+ if (evcon->conn_address != NULL)
+ mm_free(evcon->conn_address);
+
mm_free(evcon);
}
struct evhttp_connection *evcon = arg;
int error;
ev_socklen_t errsz = sizeof(error);
+ socklen_t conn_address_len = sizeof(*evcon->conn_address);
if (evcon->fd == -1)
evcon->fd = bufferevent_getfd(bufev);
evcon->retry_cnt = 0;
evcon->state = EVCON_IDLE;
+ if (!evcon->conn_address) {
+ evcon->conn_address = mm_malloc(sizeof(*evcon->conn_address));
+ }
+ if (getpeername(evcon->fd, (struct sockaddr *)evcon->conn_address, &conn_address_len)) {
+ mm_free(evcon->conn_address);
+ evcon->conn_address = NULL;
+ }
+
/* reset the bufferevent cbs */
bufferevent_setcb(evcon->bufev,
evhttp_read_cb,
*port = evcon->port;
}
+const struct sockaddr*
+evhttp_connection_get_addr(struct evhttp_connection *evcon)
+{
+ return (struct sockaddr *)evcon->conn_address;
+}
+
int
evhttp_connection_connect_(struct evhttp_connection *evcon)
{
void evhttp_connection_get_peer(struct evhttp_connection *evcon,
char **address, ev_uint16_t *port);
+/** Get the remote address associated with this connection.
+ * extracted from getpeername().
+ *
+ * @return NULL if getpeername() return non success,
+ * or connection is not connected,
+ * otherwise it return pointer to struct sockaddr_storage */
+const struct sockaddr*
+evhttp_connection_get_addr(struct evhttp_connection *evcon);
+
/**
Make an HTTP request over the specified connection.