Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Aug 2009 12:17:21 +0900
From:      Denis Berezhnoy <denis.berezhnoy@gmail.com>
To:        Adrian Penisoara <ady@freebsd.ady.ro>
Cc:        freebsd-net@freebsd.org
Subject:   Re: kevent behavior with TCP socket
Message-ID:  <18b5e36e0908092017o1d014262t45ef7cab7df098f0@mail.gmail.com>
In-Reply-To: <78cb3d3f0908090438n63eefbb2t462385e8fcfb2395@mail.gmail.com>
References:  <18b5e36e0908060115g76a56da3qb23fdd208e7c4a4c@mail.gmail.com> <18b5e36e0908080142o5914903n335ebae17e82e985@mail.gmail.com> <78cb3d3f0908090438n63eefbb2t462385e8fcfb2395@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Adrian,
Thank for your answer! I checked that nobody listens for loopback address:

[denis@freebsd ~]$ sockstat -4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS

denis    sshd       95390 3  tcp4   192.168.1.103:22
192.168.11.26:53616
root     sshd       95387 3  tcp4   192.168.1.103:22
192.168.11.26:53616
denis    sshd       95324 3  tcp4   192.168.1.103:22
192.168.11.26:53608
root     sshd       95321 3  tcp4   192.168.1.103:22
192.168.11.26:53608
root     sshd       8149  4  tcp4   *:22                  *:*
root     inetd      870   5  tcp4   *:21                  *:*
root     inetd      870   6  tcp4   *:23                  *:*
root     sendmail   821   4  tcp4   127.0.0.1:25          *:*
root     syslogd    689   7  udp4   *:514                 *:*
[denis@freebsd ~]$


I printed out fflags. Here is the result:

Kevent event num 1 wait time 46
Event filter -2 flag 0 filter flags 0 data 43008


When I comment out the part of the code that listens socket then I have the
following output:

Kevent event num 1 wait time 23
Event filter -2 flag 32768 filter flags 61 data 32768


61 is ECONNREFUSED


And more when I make loopback address listening  and try to connect it I
still get the same output:

Socket test start
Failed to connect with server 36
Kevent event num 1 wait time 23
Event filter -2 flag 0 filter flags 0 data 43008
Socket test end

but connection is actually accepted. I am totally confused here.


Best regards,
Denis

2009/8/9 Adrian Penisoara <ady@freebsd.ady.ro>

> Hi,
>
>
> On Sat, Aug 8, 2009 at 10:42 AM, Denis Berezhnoy <
> denis.berezhnoy@gmail.com> wrote:
>
>> Hi,
>>
>> Sorry for my previous post it was completely unclear I believe. Here is
>> problem description in pure C. Can you please take a look at the code
>> below:
>>
>> #include <netinet/in.h>
>> #include <sys/socket.h>
>> #include <sys/time.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>> #include <fcntl.h>
>>
>> #include <sys/types.h>
>> #include <sys/event.h>
>> #include <sys/time.h>
>> #include <errno.h>
>>
>>
>>
>> int main(int argc, char *argv[])
>> {
>> struct sockaddr_in addr;
>> struct sockaddr_in addr2;
>>
>> int sd, cd, port, sRet;
>>
>> int sHandle;
>> int sEventNum = 0;
>>
>> struct kevent sChange;
>> struct kevent sEvent;
>>
>> struct timespec *sTimeoutPtr;
>> struct timespec sTimeout;
>>
>> struct timeval sTimeVal1 = {0,0};
>> struct timeval sTimeVal2 = {0,0};
>>
>> printf("Socket test start\n");
>>
>> sd = socket(PF_INET, SOCK_STREAM, 0);
>>
>> if ( sd < 0 )
>> {
>> printf("Server socket error\n");
>> return 0;
>> }
>>
>> port = htons(10000);
>>
>>
>> memset(&addr, 0, sizeof(addr));
>> addr.sin_family = AF_INET;
>> addr.sin_port = port;
>> addr.sin_addr.s_addr = htonl(INADDR_ANY);
>>
>> if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
>>
>> {
>> printf ("Server bind errror\n");
>> return 0;
>> }
>>
>>
>>
>> if ( listen(sd, 1) != 0 )
>> {
>> printf ("Server listen error \n");
>> return 0;
>> }
>>
>>
>> cd = socket(PF_INET, SOCK_STREAM, 0);
>>
>> if ( cd < 0 )
>> {
>> printf("Client socket error\n");
>> return 0;
>> }
>>
>> sRet = fcntl(cd, F_GETFL, 0);
>>
>> sRet |= O_NONBLOCK;
>>
>> sRet = fcntl(cd, F_SETFL, sRet);
>>
>> if (sRet < 0)
>> {
>> printf("can not set non block\n");
>> }
>>
>> port = htons(10000);
>>
>> memset(&addr2, 0, sizeof(addr2)); /* Clear struct */
>> addr2.sin_family = AF_INET; /* Internet/IP */
>> addr2.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* IP address */
>> addr2.sin_port = port; /* server port */
>>
>> /* Establish connection */
>>
>> if ((sRet = connect(cd,
>> (struct sockaddr *) &addr2,
>> sizeof(addr2))) < 0)
>> {
>>
>> printf("Failed to connect with server %d\n", errno);
>>
>> }
>>
>>
>> sHandle = kqueue();
>>
>>
>> if (sHandle == -1)
>> {
>> printf("Poll can not created queue\n");
>> }
>>
>> sTimeout.tv_sec = 0;
>> sTimeout.tv_nsec = 100000000;;
>>
>> EV_SET(&sChange, cd, EVFILT_WRITE, EV_ADD,0, 0, 0);
>>
>>
>> gettimeofday(&sTimeVal1, NULL);
>>
>> sEventNum = kevent(sHandle,
>> &sChange,
>> 1,
>> &sEvent,
>> 1,
>> &sTimeout);
>>
>> gettimeofday(&sTimeVal2, NULL);
>>
>> printf ("Kevent event num %d wait time %d \n", sEventNum,
>> sTimeVal2.tv_usec
>> - sTimeVal1.tv_usec);
>>
>> if (sEventNum == 1)
>> {
>> printf ("Event filter %d flag %d data %d \n", sEvent.filter, sEvent.flags,
>> sEvent.data);
>> }
>>
>> close(sHandle);
>>
>> close(cd);
>>
>> close(sd);
>>
>> printf("Socket test end\n");
>> }
>>
>> Program output
>>
>> Socket test start
>> Failed to connect with server 36
>> Kevent event num 1 wait time 26
>> Event filter -2 flag 0 data 43008
>> Socket test end
>>
>> The question is why kevent returns 1 event when server does not accept
>> connections from clients.
>>
>
>   Question: is there something listening on your loopback address
> (127.0.0.1) or all addresses at port 10000 (sockstat -4 output should be
> evident) ? If not, have you also tested with something listening on that
> address ?
>
>   If there is nothing to connect onto the loopback address then the
> connection will immediately fail. Then I believe kevent should return with a
> failure filter flag set.
>
>   One problem I see is that you are checking the action flags
> (kevent.flags) instead of the filter flags (kevent.fflags). Please re-run
> checking the sEvent.fflags field and compare with values in <sys/event.h>
> and let us/me know what do you get.
>
> Regards,
> Adrian Penisoara
> EnterpriseBSD
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?18b5e36e0908092017o1d014262t45ef7cab7df098f0>