|
Home > Archive > Unix Programming > July 2006 > Why would accept() return a strange socket descriptor value?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Why would accept() return a strange socket descriptor value?
|
|
| andrew.sch 2006-07-16, 1:20 pm |
| Dear ALL,
I'm trying to trace network activity of a proxy server using truss
utility. The final goal is to be able to track times of the requests
being processed, but for the moment I'm simply trying to learn what's
going on inside (the program is a binary with no sources available).
$ truss -t accept,listen,read,write,connect,send,re
cv,bind <program
with arguments>
listen(256, 1024, 1) = 0
accept(256, 0xF680F9A8, 0xF680FAA8, 1) = 4
recv(257, " G E T / H T T P / 1".., 4096, 0) = 398
send(257, " H T T P / 1 . 1 4 0 3".., 2151, 0) = 2151
This is the interesting part of the log. Everything is quite trivial
with exception of returned value of accept(). According to
documentation accept() should return the socket descriptor which should
be used in calls to recv() and send(). But the value returned by
accept() differs from the value used in recv()/send(), and I cannot
understand it.
I'm sure the call sequence is correct, because I initiate the HTTP
request manually from a browser.
Could somebody explain why accept() returns 4 while recv()/send() work
with 257?
Thank you in advance,
Andrew
P.S. Forgot to mention that I work on SunOS 5.8
| |
| Barry Margolin 2006-07-16, 1:20 pm |
| In article <1153058492.176300.118450@b28g2000cwb.googlegroups.com>,
"andrew.sch" <aschetinin@gmail.com> wrote:
> Dear ALL,
>
> I'm trying to trace network activity of a proxy server using truss
> utility. The final goal is to be able to track times of the requests
> being processed, but for the moment I'm simply trying to learn what's
> going on inside (the program is a binary with no sources available).
>
> $ truss -t accept,listen,read,write,connect,send,re
cv,bind <program
> with arguments>
>
> listen(256, 1024, 1) = 0
> accept(256, 0xF680F9A8, 0xF680FAA8, 1) = 4
> recv(257, " G E T / H T T P / 1".., 4096, 0) = 398
> send(257, " H T T P / 1 . 1 4 0 3".., 2151, 0) = 2151
>
> This is the interesting part of the log. Everything is quite trivial
> with exception of returned value of accept(). According to
> documentation accept() should return the socket descriptor which should
> be used in calls to recv() and send(). But the value returned by
> accept() differs from the value used in recv()/send(), and I cannot
> understand it.
> I'm sure the call sequence is correct, because I initiate the HTTP
> request manually from a browser.
>
> Could somebody explain why accept() returns 4 while recv()/send() work
> with 257?
Maybe that's a different connection than the one that was just opened.
However, I have a feeling that truss isn't displaying these arguments
correctly for some reason. Not only is it sending and receiving on a
different socket than the one that accept() returned, but the socket
that it called listen() and accept() on in the first place seems
unlikely to be right. Normally when you open a file or socket the
system assigns the lowest available descriptor, and it would be pretty
unusual for the application to have opened over 250 descriptors before
creating the network socket. If you add socket() to the list of calls
to trace, do you see a similar inconsistency between its return value
and the calls to bind() and listen()?
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
| |
| Nils O. Selåsdal 2006-07-16, 1:20 pm |
| andrew.sch wrote:
> Dear ALL,
>
> I'm trying to trace network activity of a proxy server using truss
> utility. The final goal is to be able to track times of the requests
> being processed, but for the moment I'm simply trying to learn what's
> going on inside (the program is a binary with no sources available).
>
> $ truss -t accept,listen,read,write,connect,send,re
cv,bind <program
> with arguments>
>
> listen(256, 1024, 1) = 0
> accept(256, 0xF680F9A8, 0xF680FAA8, 1) = 4
> recv(257, " G E T / H T T P / 1".., 4096, 0) = 398
> send(257, " H T T P / 1 . 1 4 0 3".., 2151, 0) = 2151
>
> This is the interesting part of the log. Everything is quite trivial
> with exception of returned value of accept(). According to
> documentation accept() should return the socket descriptor which should
> be used in calls to recv() and send(). But the value returned by
> accept() differs from the value used in recv()/send(), and I cannot
> understand it.
> I'm sure the call sequence is correct, because I initiate the HTTP
> request manually from a browser.
>
> Could somebody explain why accept() returns 4 while recv()/send() work
> with 257?
The programmer is responsible for passing the descriptor to recv/send
You see what the programmer coded.
Likely the recv/send on fd 257 is related to another client than the
one just accepted. (or the thing has a bug..)
| |
| Andrew S. 2006-07-17, 7:24 am |
| One guy in another forum wrote that the socket descriptor might by
duplicated by calling to fcntl() with F_DUPFD, and indeed this was
exactly the case.
listen(256, 1024, 1) = 0
accept(256, 0xF680F9A8, 0xF680FAA8, 1) = 4
fcntl(4, F_DUPFD, 0x00000100) = 257
fcntl(257, F_SETFD, 0x00000001) = 0
fcntl(257, F_GETFL, 0x00000000) = 2
fcntl(257, F_SETFL, 0x00000082) = 0
recv(257, " G E T / H T T P / 1".., 4096, 0) = 237
fcntl(4, F_DUPFD, 0x00000100) = 258
fcntl(258, F_SETFD, 0x00000001) = 0
send(257, " H T T P / 1 . 1 4 0 3".., 2151, 0) = 2151
fcntl(257, F_GETFL, 0x00000000) = 130
fcntl(257, F_SETFL, 0x00000002) = 0
Now I'm wondering why would the duplicate be needed? Probably for
setting flags for the descriptor, mostly for FD_CLOEXEC. And may be
also for O_NONBLOCK which is set differently for recv() and send().
Sincerely,
Andrew
| |
| Brian Utterback 2006-07-17, 1:20 pm |
| Andrew S. wrote:
> One guy in another forum wrote that the socket descriptor might by
> duplicated by calling to fcntl() with F_DUPFD, and indeed this was
> exactly the case.
>
> listen(256, 1024, 1) = 0
> accept(256, 0xF680F9A8, 0xF680FAA8, 1) = 4
> fcntl(4, F_DUPFD, 0x00000100) = 257
> fcntl(257, F_SETFD, 0x00000001) = 0
> fcntl(257, F_GETFL, 0x00000000) = 2
> fcntl(257, F_SETFL, 0x00000082) = 0
> recv(257, " G E T / H T T P / 1".., 4096, 0) = 237
> fcntl(4, F_DUPFD, 0x00000100) = 258
> fcntl(258, F_SETFD, 0x00000001) = 0
> send(257, " H T T P / 1 . 1 4 0 3".., 2151, 0) = 2151
> fcntl(257, F_GETFL, 0x00000000) = 130
> fcntl(257, F_SETFL, 0x00000002) = 0
>
> Now I'm wondering why would the duplicate be needed? Probably for
> setting flags for the descriptor, mostly for FD_CLOEXEC. And may be
> also for O_NONBLOCK which is set differently for recv() and send().
No, those can be done on the existing file descriptor. The reason
that a programmer would dup a low numbered file descriptor to a
higher one, is to keep the low numbers available for legacy API's
like stdio, which can only deal with file descriptors below 256.
I am at a loss to explain why you would want to dup a single
duplex FD into two simplex ones, though.
--
blu
Roses are #FF0000, Violets are #0000FF. All my base are belong to you.
----------------------------------------------------------------------
Brian Utterback - OP/N1 RPE, Sun Microsystems, Inc.
Ph:877-259-7345, Em:brian.utterback-at-ess-you-enn-dot-kom
| |
| Maxim Yegorushkin 2006-07-17, 7:19 pm |
|
Brian Utterback wrote:
> Andrew S. wrote:
>
> No, those can be done on the existing file descriptor. The reason
> that a programmer would dup a low numbered file descriptor to a
> higher one, is to keep the low numbers available for legacy API's
> like stdio,
I'd like to know when and by whom stdio was depricated. Or was it
depricated with sun os altogether? ))
> which can only deal with file descriptors below 256.
Are you saying that libc can not deal with fds >= 0x100? Or is it sun
libc only?
| |
| Barry Margolin 2006-07-18, 1:20 am |
| In article <1153172023.085630.16280@p79g2000cwp.googlegroups.com>,
"Maxim Yegorushkin" <maxim.yegorushkin@gmail.com> wrote:
> Brian Utterback wrote:
>
> I'd like to know when and by whom stdio was depricated. Or was it
> depricated with sun os altogether? ))
Who said it was deprecated? "Legacy" does not mean "obsolete", it just
means "old".
>
>
> Are you saying that libc can not deal with fds >= 0x100? Or is it sun
> libc only?
Most early libc implementations used an unsigned char as the fd member
of the FILE structure, and it has been difficult for vendors to change
this and maintain backward compatibility across OS versions, because
many stdio functions are implemented as macros rather than API calls.
If the structure were changed, almost every app would have to be
recompiled to accomodate it.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
| |
| Maxim Yegorushkin 2006-07-18, 7:27 am |
|
Barry Margolin wrote:
[]
>
> Who said it was deprecated? "Legacy" does not mean "obsolete", it just
> means "old".
>
>
> Most early libc implementations used an unsigned char as the fd member
> of the FILE structure, and it has been difficult for vendors to change
> this and maintain backward compatibility across OS versions, because
> many stdio functions are implemented as macros rather than API calls.
> If the structure were changed, almost every app would have to be
> recompiled to accomodate it.
Luckily, glibc uses int to store file descriptor in FILE structure.
|
|
|
|
|