mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-05 17:15:45 +00:00
ss: Drop list traversal from unix_stats_print()
Although this complicates the dedicated procfs-based code path in unix_show() a bit, it's the only sane way to get rid of unix_show_sock() output diverging from other socket types in that it prints all socket details in a new line. As a side effect, it allows to eliminate all procfs specific code in the same function. Signed-off-by: Phil Sutter <phil@nwl.cc>
This commit is contained in:
parent
5f27ac1db9
commit
2d0e538f3e
137
misc/ss.c
137
misc/ss.c
@ -3018,15 +3018,13 @@ int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT,
|
|||||||
|
|
||||||
#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
|
#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
|
||||||
|
|
||||||
static void unix_list_free(struct sockstat *list)
|
static void unix_list_drop_first(struct sockstat **list)
|
||||||
{
|
{
|
||||||
while (list) {
|
struct sockstat *s = *list;
|
||||||
struct sockstat *s = list;
|
|
||||||
|
|
||||||
list = list->next;
|
(*list) = (*list)->next;
|
||||||
free(s->name);
|
free(s->name);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool unix_type_skip(struct sockstat *s, struct filter *f)
|
static bool unix_type_skip(struct sockstat *s, struct filter *f)
|
||||||
@ -3045,61 +3043,18 @@ static bool unix_use_proc(void)
|
|||||||
return getenv("PROC_NET_UNIX") || getenv("PROC_ROOT");
|
return getenv("PROC_NET_UNIX") || getenv("PROC_ROOT");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unix_stats_print(struct sockstat *list, struct filter *f)
|
static void unix_stats_print(struct sockstat *s, struct filter *f)
|
||||||
{
|
{
|
||||||
struct sockstat *s;
|
|
||||||
char *peer;
|
|
||||||
bool use_proc = unix_use_proc();
|
|
||||||
char port_name[30] = {};
|
char port_name[30] = {};
|
||||||
|
|
||||||
for (s = list; s; s = s->next) {
|
sock_state_print(s);
|
||||||
if (!(f->states & (1 << s->state)))
|
|
||||||
continue;
|
|
||||||
if (unix_type_skip(s, f))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
peer = "*";
|
sock_addr_print(s->name ?: "*", " ",
|
||||||
if (s->peer_name)
|
int_to_str(s->lport, port_name), NULL);
|
||||||
peer = s->peer_name;
|
sock_addr_print(s->peer_name ?: "*", " ",
|
||||||
|
int_to_str(s->rport, port_name), NULL);
|
||||||
|
|
||||||
if (s->rport && use_proc) {
|
proc_ctx_print(s);
|
||||||
struct sockstat *p;
|
|
||||||
|
|
||||||
for (p = list; p; p = p->next) {
|
|
||||||
if (s->rport == p->lport)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p) {
|
|
||||||
peer = "?";
|
|
||||||
} else {
|
|
||||||
peer = p->name ? : "*";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_proc && f->f) {
|
|
||||||
struct sockstat st = {
|
|
||||||
.local.family = AF_UNIX,
|
|
||||||
.remote.family = AF_UNIX,
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(st.local.data, &s->name, sizeof(s->name));
|
|
||||||
if (strcmp(peer, "*"))
|
|
||||||
memcpy(st.remote.data, &peer, sizeof(peer));
|
|
||||||
if (run_ssfilter(f->f, &st) == 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sock_state_print(s);
|
|
||||||
|
|
||||||
sock_addr_print(s->name ?: "*", " ",
|
|
||||||
int_to_str(s->lport, port_name), NULL);
|
|
||||||
sock_addr_print(peer, " ", int_to_str(s->rport, port_name),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
proc_ctx_print(s);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
||||||
@ -3148,8 +3103,6 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
|||||||
|
|
||||||
unix_stats_print(&stat, f);
|
unix_stats_print(&stat, f);
|
||||||
|
|
||||||
if (show_mem || show_details)
|
|
||||||
printf("\t");
|
|
||||||
if (show_mem)
|
if (show_mem)
|
||||||
print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
|
print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
|
||||||
if (show_details) {
|
if (show_details) {
|
||||||
@ -3160,8 +3113,7 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
|||||||
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (show_mem || show_details)
|
printf("\n");
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3252,6 +3204,11 @@ static int unix_show(struct filter *f)
|
|||||||
if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport)
|
if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport)
|
||||||
u->state = SS_ESTABLISHED;
|
u->state = SS_ESTABLISHED;
|
||||||
}
|
}
|
||||||
|
if (unix_type_skip(u, f) ||
|
||||||
|
!(f->states & (1 << u->state))) {
|
||||||
|
free(u);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!newformat) {
|
if (!newformat) {
|
||||||
u->rport = 0;
|
u->rport = 0;
|
||||||
@ -3259,6 +3216,42 @@ static int unix_show(struct filter *f)
|
|||||||
u->wq = 0;
|
u->wq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name[0]) {
|
||||||
|
u->name = strdup(name);
|
||||||
|
if (!u->name)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->rport) {
|
||||||
|
struct sockstat *p;
|
||||||
|
|
||||||
|
for (p = list; p; p = p->next) {
|
||||||
|
if (u->rport == p->lport)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!p)
|
||||||
|
u->peer_name = "?";
|
||||||
|
else
|
||||||
|
u->peer_name = p->name ? : "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->f) {
|
||||||
|
struct sockstat st = {
|
||||||
|
.local.family = AF_UNIX,
|
||||||
|
.remote.family = AF_UNIX,
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(st.local.data, &u->name, sizeof(u->name));
|
||||||
|
if (strcmp(u->peer_name, "*"))
|
||||||
|
memcpy(st.remote.data, &u->peer_name,
|
||||||
|
sizeof(u->peer_name));
|
||||||
|
if (run_ssfilter(f->f, &st) == 0) {
|
||||||
|
free(u->name);
|
||||||
|
free(u);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
insp = &list;
|
insp = &list;
|
||||||
while (*insp) {
|
while (*insp) {
|
||||||
if (u->type < (*insp)->type ||
|
if (u->type < (*insp)->type ||
|
||||||
@ -3270,24 +3263,22 @@ static int unix_show(struct filter *f)
|
|||||||
u->next = *insp;
|
u->next = *insp;
|
||||||
*insp = u;
|
*insp = u;
|
||||||
|
|
||||||
if (name[0]) {
|
|
||||||
if ((u->name = malloc(strlen(name)+1)) == NULL)
|
|
||||||
break;
|
|
||||||
strcpy(u->name, name);
|
|
||||||
}
|
|
||||||
if (++cnt > MAX_UNIX_REMEMBER) {
|
if (++cnt > MAX_UNIX_REMEMBER) {
|
||||||
unix_stats_print(list, f);
|
while (list) {
|
||||||
unix_list_free(list);
|
unix_stats_print(list, f);
|
||||||
list = NULL;
|
printf("\n");
|
||||||
|
|
||||||
|
unix_list_drop_first(&list);
|
||||||
|
}
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (list) {
|
while (list) {
|
||||||
unix_stats_print(list, f);
|
unix_stats_print(list, f);
|
||||||
unix_list_free(list);
|
printf("\n");
|
||||||
list = NULL;
|
|
||||||
cnt = 0;
|
unix_list_drop_first(&list);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user