My application relies heavily on the constant number of chars in a line of /proc/net/tcp* files
/proc/net/tcp does pad have such constancy
0: 000000:006F .......
1: 000000:DD36 .......
2: 000000:B23A .......
We know that 1 is exactly 150 chars after 0 and 2 is exactly 150 chars after 1 and so forth.
There is no such consistency with /proc/net/tcp6, i.e.
sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000000000000000000000000000:DD36 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 162811 1 ea464b00 300 0 0 2 -1
1: 0000000000000000FFFF00000100007F:225B 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 109176 1 ea464000 300 0 0 2 -1
2: 0000000000000000FFFF00007201A8C0:A4F4 0000000000000000FFFF000009A6D38C:0050 08 00000000:00000001 00:00000000 00000000 1000 0 3128779 1 c210f700 66 4 0 3 2
3: 0000000000000000FFFF00007201A8C0:AD90 0000000000000000FFFF00001AC64F42:0050 08 00000000:00000001 00:00000000 00000000 1000 0 3128796 1 ea465600 4800 4 0 3 2
4: 0000000000000000FFFF00007201A8C0:DD24 0000000000000000FFFF00002CD8D2CF:0050 01 00000000:00000000 00:00000000 00000000 1000 0 3128263 1 c210ec00 295 0 0 3 2
5: 0000000000000000FFFF00007201A8C0:BBC6 0000000000000000FFFF000063E8B244:0050 01 00000000:00000000 00:00000000 00000000 1000 0 3128375 1 c210c580 4800 0 0 4 2
(word wrap need to turned off when viewing this to better understand my point.
Here the amount of chars fluctuate:
between 0 and 1 = 170 chars
between 1 and 2 = 170 chars
between 2 and 3 = 169 chars
between 3 and 4 = 171 chars
between 4 and 5 = 170 chars
Is it possible to implement a constant amount of chars in one line just like in /proc/net/tcp.
This is very helpful for parsing when you extract i.e. the source port, then seek 150 chars and extract the next line's source port and so on.
My application parses /proc/net/tcp6 at least 4 times per second, so the overhead of figuring out the length of each line and subtracting the offset is quite expensive.
P.S. Please CC me when replying to this thread
My application parses /proc/net/tcp6 at least 4 times per
second, so the overhead of figuring out the length of each
line and subtracting the offset is quite expensive.
I'd be surprised if you can detect the cost of calling
strchr(buf, '\n') on each line at the frequency.
It is probably far less than the other processing you
do on the line.
David
On Tue, 17 Jan 2012 13:33:01 -0000
"David Laight" [off-list ref] wrote:
quoted
My application parses /proc/net/tcp6 at least 4 times per
second, so the overhead of figuring out the length of each
line and subtracting the offset is quite expensive.
I'd be surprised if you can detect the cost of calling
strchr(buf, '\n') on each line at the frequency.
It is probably far less than the other processing you
do on the line.
David
Thank you, David. I first fread() the whole file to membuf and then process it thusly trying to find a line that matches my source port (porthex) :
while(1){
memcpy(buffer,&tcp6_membuf[184+170*i],4);
if ( !memcmp ( porthex, buffer, 4 ) ){ //match!
goto endloop;
}
i++;
continue;
N.B. 184 is the offset of source port on line 2 from the beginning of file (line 1 is used for column headings)
my /proc/net/tcp6 file contains 300 - 500 lines and I parse it at least from 4 to 10 times per sec. So the maximum is 5000 iterations per sec. It would be very costly CPU wise to do strchr(buf, '\n')
I'm not skillful enough to understand the code in kernel sources.
My concern boils down to this:
Was /proc/net/tcp* meant to have an equal length of each line?
If yes, then I discovered a bug.
If no, then would it be possible to patch the kernel to enable an equal length on each line?
From: <redacted>
Date: Tue, 17 Jan 2012 15:29:19 +0000
My application relies heavily on the constant number of chars in a line of /proc/net/tcp* files
Too bad, parse the fields properly.
Le mardi 17 janvier 2012 à 16:14 +0000, abirvalg@lavabit.com a écrit :
Thank you, David. I first fread() the whole file to membuf and then process it thusly trying to find a line that matches my source port (porthex) :
while(1){
memcpy(buffer,&tcp6_membuf[184+170*i],4);
if ( !memcmp ( porthex, buffer, 4 ) ){ //match!
goto endloop;
}
i++;
continue;
Wow... no comment on this code.
N.B. 184 is the offset of source port on line 2 from the beginning of file (line 1 is used for column headings)
my /proc/net/tcp6 file contains 300 - 500 lines and I parse it at least from 4 to 10 times per sec. So the maximum is 5000 iterations per sec. It would be very costly CPU wise to do strchr(buf, '\n')
I'm not skillful enough to understand the code in kernel sources.
My concern boils down to this:
Was /proc/net/tcp* meant to have an equal length of each line?
If yes, then I discovered a bug.
If no, then would it be possible to patch the kernel to enable an equal length on each line?
netlink can give you the needed information much faster.
Take a look at what is done by :
"ss -emoi src :22"
State Recv-Q Send-Q Local Address:Port
Peer Address:Port
ESTAB 0 0 192.168.20.108:22
10.37.168.20:39444 timer:(keepalive,115min,0) ino:6852
sk:ffff88011ca81900
mem:(r0,w0,f8192,t0) ts sack cubic wscale:4,4 rto:208 rtt:8/11 ato:51
cwnd:10 ssthresh:24 send 14.5Mbps rcv_rtt:15 rcv_space:14480
sendmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(3)=[{"`\0\0\0\22\0\1\3@\342\1\0\0\0\0\0\2\0\0\17\0\0\0\0\0\0\0\0
\0\0\0\0"..., 76}, {"\24\0\1\0", 4}, {"\7\20\24\0\0\0\0\0\26\0\0\0\0\0\0
\0", 16}], msg_controllen=0, msg_flags=0}, 0) = 96
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(1)=[{"\344\0\0\0\22\0\2\0@\342\1\0l\f\0\0\2\1\1\0\0\26\232\24
\300\250\24l320 "..., 8192}], msg_controllen=0, msg_flags=0}, 0) = 228
One sendmsg() for the request, one recvmsg() for the answer (with _all_
details included), even if your /proc/net/tcp*** has 1.000.000 lines.
Really say no to /proc files.
From: Eric Dumazet <redacted>
Date: Tue, 17 Jan 2012 16:13:17 +0100
One sendmsg() for the request, one recvmsg() for the answer (with _all_
details included), even if your /proc/net/tcp*** has 1.000.000 lines.
Really say no to /proc files.
Indeed.