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>