Bug #4442
opent_bind() does not return negotiated qlen for /dev/tcp
0%
Description
According to the t_bind(3nsl) man page t_bind() should return negotiated qlen (maximum number of outstanding connection indications) in ret parameter. This works properly for /dev/ticots and /dev/ticotsord, but it does not work for /dev/tcp.
The maximum number of outstanding connection indications for /dev/tcp is in tcp_conn_req_max_q and it is 128 by default:
$ ndd -get /dev/tcp tcp_conn_req_max_q 128 $
Here is the testcase shoving the t_bind() does not work as expected and documented for /dev/tcp:
$ cat t_bind-test.c #include <xti.h> #include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { int fd; struct t_info tinfo; struct t_bind req; struct t_bind ret; unsigned q; if (argc != 3) { printf("Wrong arguments\\n"); return 1; } q = atoi(argv[2]); fd = t_open(argv[1], O_RDWR, &tinfo); if (fd == -1) { printf("t_open failed\\n"); return 1; } req.addr.len = 0; req.qlen = q; ret.addr.maxlen = 0; if (t_bind(fd, &req, &ret) != 0) { printf("t_bind failed\\n"); return 1; } printf("negotiated qlen: %d\\n", ret.qlen); return 0; } $ gcc -lnsl -o t_bind-test t_bind-test.c $ ./t_bind-test /dev/ticots 10000 negotiated qlen: 4096 $ ./t_bind-test /dev/ticotsord 10000 negotiated qlen: 4096 $ ./t_bind-test /dev/ticlts 10000 negotiated qlen: 0 $ ./t_bind-test /dev/tcp 10000 negotiated qlen: 10000 $ ./t_bind-test /dev/udp 10000 negotiated qlen: 10000 $
The expected result for /dev/tcp above is 128.
Updated by Sachidananda Urs almost 8 years ago
Marcel,
Man page says:
The qlen field has meaning only when initializing a connection-mode service. It specifies the number of outstanding connection indications that the transport provider should support for the given transport endpoint. An outstanding connection indication is one that has been passed to the transport user by the transport provider but which has not been accepted or rejected. A value of qlen greater than zero is only meaningful when issued by a passive transport user that expects other users to call it. The value of qlen will be negotiated by the transport provider and may be changed if the transport provider cannot support the specified number of outstanding connection indications. However, this value of qlen will never be negotiated from a requested value greater than zero to zero. This is a requirement on transport providers; see WARNINGS below. On return, the qlen field in ret will contain the negotiated value.
And the ipadm command output:
root@odin:/export/home/sac/tmp/4442# ipadm set-prop -p _conn_req_max_q=1024 tcp root@odin:/export/home/sac/tmp/4442# ipadm show-prop -p _conn_req_max_q tcp PROTO PROPERTY PERM CURRENT PERSISTENT DEFAULT POSSIBLE tcp _conn_req_max_q rw 1024 1024 128 1-4294967295 root@odin:/export/home/sac/tmp/4442# ipadm set-prop -p _conn_req_max_q=4294967295 tcp root@odin:/export/home/sac/tmp/4442# ipadm show-prop -p _conn_req_max_q tcp PROTO PROPERTY PERM CURRENT PERSISTENT DEFAULT POSSIBLE tcp _conn_req_max_q rw 4294967295 4294967295 128 1-4294967295 root@odin:/export/home/sac/tmp/4442#
It matches your reproducer program output, i.e negotiated qlen is 1000, and the transport end-point
supports so many outstanding connection indications.
I may be wrong, I was just trying to figure this out. Please correct me if I'm missing something.
Updated by Marcel Telka almost 8 years ago
Sachidananda Urs wrote:
It matches your reproducer program output, i.e negotiated qlen is 1000, and the transport end-point
supports so many outstanding connection indications.
I do not see 1000 neither in your output, nor in my testcase. I do not understand what exactly you are trying to show using the ipadm commands. Please elaborate. Thanks.
Updated by Sachidananda Urs almost 8 years ago
Hi Marcel,
I thought, ret.qlen would have the negotiated qlen, and for tcp valid range is 1-4294967295. And thought 10000 in your t_bind reproducer program was a valid return value.
I will dig more on this and get back to you. Please ignore this for now.
Updated by Marcel Telka almost 8 years ago
Sachidananda Urs wrote:
I thought, ret.qlen would have the negotiated qlen, and for tcp valid range is 1-4294967295. And thought 10000 in your t_bind reproducer program was a valid return value.
Yes, the ret.qlen would have the negotiated qlen. The problem is that tcp_conn_req_max_q contains the max value of the negotiated qlen (for TCP), so any negotation cannot exceed this value (128 by default). Since we do see the "negotiated" qlen as 10000 (while the max is 128), it means that either the TCP was able to negotiate higher value than the max (I believe this is not the case), or t_bind() does not return the actually negotiated qlen, but instead it automatically returns the requested qlen, even the negotiated qlen is different (I believe this is the problem).