Skip to content

Commit

Permalink
Thread pid lookup support through the NAT API.
Browse files Browse the repository at this point in the history
This exposes the pid lookup code as a standard attribute
of NAT lookup -- if a matching process cannot be found,
or if pid lookup isn't supported by the NAT backend,
a pid of -1 is returned.

This also adds the local_pid to the pxyconn context; this
will be used to populate log strings.
  • Loading branch information
landonf committed Oct 18, 2014
1 parent bcc7438 commit 9204418
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 25 deletions.
62 changes: 39 additions & 23 deletions nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,20 @@ nat_pf_fini(void)

#ifdef HAVE_DARWIN_LIBPROC
static int
nat_pf_lookup_proc(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
evutil_socket_t s,
struct sockaddr *src_addr, UNUSED socklen_t src_addrlen)
nat_pf_lookup_proc(pid_t *result, struct sockaddr *dst_addr, UNUSED socklen_t *dst_addrlen)
{
pid_t *pids = NULL;
struct proc_fdinfo *fds = NULL;
int ret = -1;

/* default result if no pid matches */
*result = -1;

/* iterate over all pids to find a matching socket */
int pid_count = proc_listallpids(NULL, 0);
pids = malloc(sizeof(pid_t) * pid_count);
if (!pids) {
goto error;
goto done;
}

pid_count = proc_listallpids(pids, sizeof(pid_t) * pid_count);
Expand All @@ -149,7 +151,7 @@ nat_pf_lookup_proc(struct sockaddr *dst_addr, socklen_t *dst_addrlen,

fds = malloc(PROC_PIDLISTFD_SIZE * fd_count);
if (!fds) {
goto error;
goto done;
}
fd_count = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds, sizeof(fds[0]) * fd_count);

Expand Down Expand Up @@ -193,27 +195,32 @@ nat_pf_lookup_proc(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
}
}

// TODO
char name[MAXPATHLEN];
proc_pidpath(pid, name, sizeof(name));
log_err_printf("Matched socket to process %s\n", name);

free(pids);
free(fds);
return 0;
/* valid match */
*result = pid;
ret = 0;
goto done;
}
}

error:
done:
free(pids);
free(fds);
return -1;
return ret;
}
#endif

#else /* HAVE_DARWIN_LIBPROC */

static int
nat_pf_lookup_proc(pid_t *result, struct sockaddr *dst_addr, UNUSED socklen_t *dst_addrlen) {
*result = -1;
return 0;
}

#endif /* !HAVE_DARWIN_LIBPROC */

static int
nat_pf_lookup_cb(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
evutil_socket_t s,
pid_t *pid, evutil_socket_t s,
struct sockaddr *src_addr, UNUSED socklen_t src_addrlen)
{
#ifdef __APPLE__
Expand Down Expand Up @@ -287,9 +294,9 @@ nat_pf_lookup_cb(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
*dst_addrlen = sizeof(struct sockaddr_in6);
}

// TODO
if (nat_pf_lookup_proc(dst_addr, dst_addrlen, s, src_addr, src_addrlen) == -1) {
log_err_printf("lookup failed\n");
/* find the local process; there may be none. */
if (nat_pf_lookup_proc(pid, dst_addr, dst_addrlen) == -1) {
return -1;
}

return 0;
Expand Down Expand Up @@ -344,14 +351,17 @@ nat_ipfilter_fini(void)

static int
nat_ipfilter_lookup_cb(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
evutil_socket_t s,
pid_t *pid, evutil_socket_t s,
struct sockaddr *src_addr, UNUSED socklen_t src_addrlen)
{
struct sockaddr_storage our_addr;
socklen_t our_addrlen;
struct natlookup nl;
struct ipfobj ipfo;

/* pid lookup is unsupported. */
*pid = -1;

our_addrlen = sizeof(struct sockaddr_storage);
if (getsockname(s, (struct sockaddr *)&our_addr, &our_addrlen) == -1) {
log_err_printf("Error from getsockname(): %s\n",
Expand Down Expand Up @@ -423,12 +433,15 @@ nat_ipfilter_lookup_cb(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
*/
static int
nat_netfilter_lookup_cb(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
evutil_socket_t s,
pid_t *pid, evutil_socket_t s,
struct sockaddr *src_addr,
UNUSED socklen_t src_addrlen)
{
int rv;

/* pid lookup is unsupported. */
*pid = -1;

if (src_addr->sa_family != AF_INET) {
log_err_printf("The netfilter NAT engine only "
"supports IPv4 state lookups\n");
Expand Down Expand Up @@ -477,10 +490,13 @@ nat_iptransparent_socket_cb(evutil_socket_t s)
*/
static int
nat_getsockname_lookup_cb(struct sockaddr *dst_addr, socklen_t *dst_addrlen,
evutil_socket_t s,
pid_t *pid, evutil_socket_t s,
UNUSED struct sockaddr *src_addr,
UNUSED socklen_t src_addrlen)
{
/* pid lookup is unsupported. */
*pid = -1;

if (getsockname(s, dst_addr, dst_addrlen) == -1) {
log_err_printf("Error from getsockname(): %s\n",
strerror(errno));
Expand Down
3 changes: 2 additions & 1 deletion nat.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@

#include <event2/util.h>

typedef int (*nat_lookup_cb_t)(struct sockaddr *, socklen_t *, evutil_socket_t,
typedef int (*nat_lookup_cb_t)(struct sockaddr *, socklen_t *,
pid_t *, evutil_socket_t s,
struct sockaddr *, socklen_t);
typedef int (*nat_socket_cb_t)(evutil_socket_t);

Expand Down
14 changes: 13 additions & 1 deletion pxyconn.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ typedef struct pxy_conn_ctx {
unsigned int enomem : 1; /* 1 if out of memory */
unsigned int sni_peek_retries : 6; /* max 64 SNI parse retries */

/* local process id, or -1 */
pid_t local_pid;

/* server name indicated by client in SNI TLS extension */
char *sni;

Expand Down Expand Up @@ -173,6 +176,7 @@ pxy_conn_ctx_new(proxyspec_t *spec, opts_t *opts,
ctx->spec = spec;
ctx->opts = opts;
ctx->fd = fd;
ctx->local_pid = -1;
ctx->thridx = pxy_thrmgr_attach(thrmgr, &ctx->evbase, &ctx->dnsbase);
ctx->thrmgr = thrmgr;
#ifdef DEBUG_PROXY
Expand Down Expand Up @@ -1845,7 +1849,7 @@ pxy_conn_setup(evutil_socket_t fd,
/* NAT engine lookup */
ctx->addrlen = sizeof(struct sockaddr_storage);
if (spec->natlookup((struct sockaddr *)&ctx->addr,
&ctx->addrlen, fd,
&ctx->addrlen, &ctx->local_pid, fd,
peeraddr, peeraddrlen) == -1) {
log_err_printf("Connection not found in NAT "
"state table, aborting connection\n");
Expand Down Expand Up @@ -1874,6 +1878,14 @@ pxy_conn_setup(evutil_socket_t fd,
ctx->src_str = sys_sockaddr_str(peeraddr, peeraddrlen);
if (!ctx->src_str)
goto memout;

if (ctx->local_pid != -1) {
// TODO
#include <libproc.h>
char name[MAXPATHLEN];
proc_pidpath(ctx->local_pid, name, sizeof(name));
log_err_printf("Matched socket to process %s\n", name);
}
}

/* for SSL, defer dst connection setup to initial_readcb */
Expand Down

0 comments on commit 9204418

Please sign in to comment.