mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-05 22:35:10 +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))
|
||||
|
||||
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;
|
||||
free(s->name);
|
||||
free(s);
|
||||
}
|
||||
(*list) = (*list)->next;
|
||||
free(s->name);
|
||||
free(s);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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] = {};
|
||||
|
||||
for (s = list; s; s = s->next) {
|
||||
if (!(f->states & (1 << s->state)))
|
||||
continue;
|
||||
if (unix_type_skip(s, f))
|
||||
continue;
|
||||
sock_state_print(s);
|
||||
|
||||
peer = "*";
|
||||
if (s->peer_name)
|
||||
peer = s->peer_name;
|
||||
sock_addr_print(s->name ?: "*", " ",
|
||||
int_to_str(s->lport, port_name), NULL);
|
||||
sock_addr_print(s->peer_name ?: "*", " ",
|
||||
int_to_str(s->rport, port_name), NULL);
|
||||
|
||||
if (s->rport && use_proc) {
|
||||
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");
|
||||
}
|
||||
proc_ctx_print(s);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (show_mem || show_details)
|
||||
printf("\t");
|
||||
if (show_mem)
|
||||
print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
|
||||
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 ? '-' : '>');
|
||||
}
|
||||
}
|
||||
if (show_mem || show_details)
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3252,6 +3204,11 @@ static int unix_show(struct filter *f)
|
||||
if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport)
|
||||
u->state = SS_ESTABLISHED;
|
||||
}
|
||||
if (unix_type_skip(u, f) ||
|
||||
!(f->states & (1 << u->state))) {
|
||||
free(u);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!newformat) {
|
||||
u->rport = 0;
|
||||
@ -3259,6 +3216,42 @@ static int unix_show(struct filter *f)
|
||||
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;
|
||||
while (*insp) {
|
||||
if (u->type < (*insp)->type ||
|
||||
@ -3270,24 +3263,22 @@ static int unix_show(struct filter *f)
|
||||
u->next = *insp;
|
||||
*insp = u;
|
||||
|
||||
if (name[0]) {
|
||||
if ((u->name = malloc(strlen(name)+1)) == NULL)
|
||||
break;
|
||||
strcpy(u->name, name);
|
||||
}
|
||||
if (++cnt > MAX_UNIX_REMEMBER) {
|
||||
unix_stats_print(list, f);
|
||||
unix_list_free(list);
|
||||
list = NULL;
|
||||
while (list) {
|
||||
unix_stats_print(list, f);
|
||||
printf("\n");
|
||||
|
||||
unix_list_drop_first(&list);
|
||||
}
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
if (list) {
|
||||
while (list) {
|
||||
unix_stats_print(list, f);
|
||||
unix_list_free(list);
|
||||
list = NULL;
|
||||
cnt = 0;
|
||||
printf("\n");
|
||||
|
||||
unix_list_drop_first(&list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user