shared/socket-util: add function to query remote address
This commit is contained in:
parent
ad95fd1d2b
commit
b31f535c9a
|
@ -31,6 +31,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
|
@ -574,13 +575,12 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
|
|||
|
||||
int getpeername_pretty(int fd, char **ret) {
|
||||
union sockaddr_union sa;
|
||||
socklen_t salen;
|
||||
socklen_t salen = sizeof(sa);
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
salen = sizeof(sa);
|
||||
if (getpeername(fd, &sa.sa, &salen) < 0)
|
||||
return -errno;
|
||||
|
||||
|
@ -608,12 +608,11 @@ int getpeername_pretty(int fd, char **ret) {
|
|||
|
||||
int getsockname_pretty(int fd, char **ret) {
|
||||
union sockaddr_union sa;
|
||||
socklen_t salen;
|
||||
socklen_t salen = sizeof(sa);
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
salen = sizeof(sa);
|
||||
if (getsockname(fd, &sa.sa, &salen) < 0)
|
||||
return -errno;
|
||||
|
||||
|
@ -625,6 +624,49 @@ int getsockname_pretty(int fd, char **ret) {
|
|||
return sockaddr_pretty(&sa.sa, salen, false, ret);
|
||||
}
|
||||
|
||||
int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
|
||||
int r;
|
||||
char host[NI_MAXHOST], *ret;
|
||||
|
||||
assert(_ret);
|
||||
|
||||
r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
|
||||
NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
|
||||
if (r != 0) {
|
||||
_cleanup_free_ char *sockname = NULL;
|
||||
int saved_errno = errno;
|
||||
|
||||
r = sockaddr_pretty(&sa->sa, salen, true, &sockname);
|
||||
if (r < 0)
|
||||
log_error("sockadd_pretty() failed: %s", strerror(-r));
|
||||
else
|
||||
log_error("getnameinfo(%s) failed: %s", sockname, strerror(-r));
|
||||
return -saved_errno;
|
||||
}
|
||||
|
||||
ret = strdup(host);
|
||||
if (!ret)
|
||||
return log_oom();
|
||||
|
||||
*_ret = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getnameinfo_pretty(int fd, char **ret) {
|
||||
union sockaddr_union sa;
|
||||
socklen_t salen = sizeof(sa);
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
if (getsockname(fd, &sa.sa, &salen) < 0) {
|
||||
log_error("getsockname(%d) failed: %m", fd);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return socknameinfo_pretty(&sa, salen, ret);
|
||||
}
|
||||
|
||||
int socket_address_unlink(SocketAddress *a) {
|
||||
assert(a);
|
||||
|
||||
|
|
|
@ -101,6 +101,9 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
|
|||
int getpeername_pretty(int fd, char **ret);
|
||||
int getsockname_pretty(int fd, char **ret);
|
||||
|
||||
int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);
|
||||
int getnameinfo_pretty(int fd, char **ret);
|
||||
|
||||
const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_;
|
||||
SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "util.h"
|
||||
#include "macro.h"
|
||||
#include "log.h"
|
||||
#include "async.h"
|
||||
|
||||
static void test_socket_address_parse(void) {
|
||||
SocketAddress a;
|
||||
|
@ -212,6 +213,58 @@ static void test_in_addr_prefix_next(void) {
|
|||
|
||||
}
|
||||
|
||||
static void *connect_thread(void *arg) {
|
||||
union sockaddr_union *sa = arg;
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
assert(fd >= 0);
|
||||
|
||||
assert_se(connect(fd, &sa->sa, sizeof(sa->in)) == 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_nameinfo_pretty(void) {
|
||||
_cleanup_free_ char *stdin = NULL, *localhost = NULL;
|
||||
|
||||
union sockaddr_union s = {
|
||||
.in.sin_family = AF_INET,
|
||||
.in.sin_port = 0,
|
||||
.in.sin_addr.s_addr = htonl(INADDR_ANY),
|
||||
};
|
||||
int r;
|
||||
|
||||
union sockaddr_union c = {};
|
||||
socklen_t slen = sizeof(c.in), clen = sizeof(c.in);
|
||||
|
||||
_cleanup_close_ int sfd = -1, cfd = -1, afd = -1;
|
||||
r = getnameinfo_pretty(STDIN_FILENO, &stdin);
|
||||
log_info("No connection remote: %s", strerror(-r));
|
||||
|
||||
assert_se(r < 0);
|
||||
|
||||
sfd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0);
|
||||
assert(sfd >= 0);
|
||||
|
||||
assert_se(bind(sfd, &s.sa, sizeof(s.in)) == 0);
|
||||
|
||||
/* find out the port number */
|
||||
assert_se(getsockname(sfd, &s.sa, &slen) == 0);
|
||||
|
||||
assert_se(listen(sfd, 1) == 0);
|
||||
|
||||
assert_se(asynchronous_job(connect_thread, &s) == 0);
|
||||
|
||||
log_debug("Accepting new connection on fd:%d", sfd);
|
||||
cfd = accept4(sfd, &c.sa, &clen, SOCK_CLOEXEC);
|
||||
assert(cfd >= 0);
|
||||
|
||||
r = getnameinfo_pretty(cfd, &localhost);
|
||||
log_info("Connection from %s", localhost);
|
||||
assert(r == 0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
log_set_max_level(LOG_DEBUG);
|
||||
|
@ -224,5 +277,7 @@ int main(int argc, char *argv[]) {
|
|||
test_in_addr_prefix_intersect();
|
||||
test_in_addr_prefix_next();
|
||||
|
||||
test_nameinfo_pretty();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue