you're not interested in one or the other information, pass NULL as
the pointer. */
-void
+static void
sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
{
switch (sa->sa_family)
return ACCEPTOK;
}
-/* Return the local IP address associated with the connection on FD. */
+/* Get the IP address associated with the connection on FD and store
+ it to IP. Return 1 on success, 0 otherwise.
+
+ If ENDPOINT is ENDPOINT_LOCAL, it returns the address of the local
+ (client) side of the socket. Else if ENDPOINT is ENDPOINT_PEER, it
+ returns the address of the remote (peer's) side of the socket. */
int
-conaddr (int fd, ip_address *ip)
+socket_ip_address (int sock, ip_address *ip, int endpoint)
{
struct sockaddr_storage storage;
struct sockaddr *sockaddr = (struct sockaddr *)&storage;
socklen_t addrlen = sizeof (storage);
+ int ret;
- if (getsockname (fd, sockaddr, &addrlen) < 0)
+ if (endpoint == ENDPOINT_LOCAL)
+ ret = getsockname (sock, sockaddr, &addrlen);
+ else if (endpoint == ENDPOINT_PEER)
+ ret = getpeername (sock, sockaddr, &addrlen);
+ else
+ abort ();
+ if (ret < 0)
return 0;
switch (sockaddr->sa_family)
register_extended (int fd, xreader_t reader, xwriter_t writer,
xpoller_t poller, xcloser_t closer, void *ctx)
{
- struct extended_info *info = xnew (struct extended_info);
+ struct extended_info *info;
+
+ /* The file descriptor must be non-negative to be registered.
+ Negative values are ignored by xclose(), and -1 cannot be used as
+ hash key. */
+ assert (fd >= 0);
+
+ info = xnew (struct extended_info);
info->reader = reader;
info->writer = writer;
info->poller = poller;
{ \
info = hash_table_get (extended_map, (void *) fd); \
last_fd = fd; \
+ last_info = info; \
last_tick = extended_map_modified_tick; \
} \
} while (0)