Skip to content

Commit

Permalink
Add a filtercheck for when a fd name changes
Browse files Browse the repository at this point in the history
Add a filtercheck fd.name_changed which is true when parsing an event
changes the "name" of a fd. This mostly occurs when a
bind/connect/sendto/recvfrom/etc changes the ip/port information
associated with a socket fd, and is useful if you want to track when a
stream of sendto/recvfroms on a single socket changes addresses.

This is done by adding a m_oldname to fdinfo, which is set when
threadinfo returns a fd and associates it with an event. If after
parsing, the name changes, the filtercheck will return true.

Whether the name changed or not is an event property and set at the end
of sinsp_parser::process_event(). It does this by checking the original
fd name and comparing it to the fd name that exists after parsing the
event.
  • Loading branch information
mstemm committed Feb 2, 2018
1 parent 1d0d185 commit 6b35e44
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 3 deletions.
17 changes: 17 additions & 0 deletions userspace/libsinsp/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ class SINSP_PUBLIC sinsp_evt
return m_fdinfo;
}

inline bool fdinfo_name_changed()
{
return m_fdinfo_name_changed;
}

inline void set_fdinfo_name_changed(bool changed)
{
m_fdinfo_name_changed = changed;
}

/*!
\brief Return the number of the FD associated with this event.
Expand Down Expand Up @@ -333,6 +343,7 @@ class SINSP_PUBLIC sinsp_evt
m_info = &(m_event_info_table[m_pevt->type]);
m_tinfo = NULL;
m_fdinfo = NULL;
m_fdinfo_name_changed = false;
m_iosize = 0;
m_poriginal_evt = NULL;
}
Expand All @@ -343,6 +354,7 @@ class SINSP_PUBLIC sinsp_evt
m_info = &(m_event_info_table[m_pevt->type]);
m_tinfo = NULL;
m_fdinfo = NULL;
m_fdinfo_name_changed = false;
m_iosize = 0;
m_cpuid = cpuid;
m_evtnum = 0;
Expand Down Expand Up @@ -396,6 +408,11 @@ VISIBILITY_PRIVATE

sinsp_threadinfo* m_tinfo;
sinsp_fdinfo_t* m_fdinfo;

// If true, then the associated fdinfo changed names as a part
// of parsing this event.
bool m_fdinfo_name_changed;

uint32_t m_iosize;
int32_t m_errorcode;
int32_t m_rawbuf_str_len;
Expand Down
2 changes: 2 additions & 0 deletions userspace/libsinsp/fdinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class SINSP_PUBLIC sinsp_fdinfo
m_openflags = other.m_openflags;
m_sockinfo = other.m_sockinfo;
m_name = other.m_name;
m_oldname = other.m_oldname;
m_flags = other.m_flags;
m_ino = other.m_ino;

Expand Down Expand Up @@ -300,6 +301,7 @@ class SINSP_PUBLIC sinsp_fdinfo
sinsp_sockinfo m_sockinfo;

string m_name; ///< Human readable rendering of this FD. For files, this is the full file name. For sockets, this is the tuple. And so on.
string m_oldname; // The name of this fd at the beginning of event parsing. Used to detect name changes that result from parsing an event.

inline bool has_decoder_callbacks()
{
Expand Down
16 changes: 14 additions & 2 deletions userspace/libsinsp/filterchecks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ const filtercheck_field_info sinsp_filter_check_fd_fields[] =
{PT_IPV4NET, EPF_NONE, PF_NA, "fd.lnet", "local IP network."},
{PT_IPV4NET, EPF_NONE, PF_NA, "fd.rnet", "remote IP network."},
{PT_BOOL, EPF_NONE, PF_NA, "fd.connected", "for TCP/UDP FDs, 'true' if the socket is connected."},

{PT_BOOL, EPF_NONE, PF_NA, "fd.name_changed", "True when an event changes the name of an fd used by this event. This can occur in some cases such as udp connections where the connection tuple changes."}
};

sinsp_filter_check_fd::sinsp_filter_check_fd()
Expand Down Expand Up @@ -1047,7 +1047,19 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len, bool

m_tbool = m_fdinfo->is_socket_connected();

return (uint8_t*)&m_tbool;
RETURN_EXTRACT_VAR(m_tbool);
}
break;
case TYPE_NAME_CHANGED:
{
if(m_fdinfo == NULL)
{
return NULL;
}

m_tbool = evt->fdinfo_name_changed();

RETURN_EXTRACT_VAR(m_tbool);
}
break;
default:
Expand Down
1 change: 1 addition & 0 deletions userspace/libsinsp/filterchecks.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ class sinsp_filter_check_fd : public sinsp_filter_check
TYPE_LNET = 30,
TYPE_RNET = 31,
TYPE_IS_CONNECTED = 32,
TYPE_NAME_CHANGED = 33,
};

enum fd_type
Expand Down
8 changes: 8 additions & 0 deletions userspace/libsinsp/parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,14 @@ void sinsp_parser::process_event(sinsp_evt *evt)
evt->m_filtered_out = true;
}
}

// Check to see if the name changed as a side-effect of
// parsing this event. Try to avoid the overhead of a string
// compare for every event.
if(evt->m_fdinfo)
{
evt->set_fdinfo_name_changed(evt->m_fdinfo->m_name != evt->m_fdinfo->m_oldname);
}
}

void sinsp_parser::event_cleanup(sinsp_evt *evt)
Expand Down
10 changes: 9 additions & 1 deletion userspace/libsinsp/threadinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,15 @@ class SINSP_PUBLIC sinsp_threadinfo

if(fdt)
{
return fdt->find(fd);
sinsp_fdinfo_t *fdinfo = fdt->find(fd);
if(fdinfo)
{
// Its current name is now its old
// name. The name might change as a
// result of parsing.
fdinfo->m_oldname = fdinfo->m_name;
return fdinfo;
}
}

return NULL;
Expand Down

0 comments on commit 6b35e44

Please sign in to comment.