Code Comments
Programming Forum and web based access to our favorite programming groups.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
Post Follow-up to this messageIn 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 ***
Post Follow-up to this messageandrew.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..)
Post Follow-up to this messageOne 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
Post Follow-up to this messageAndrew 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
Post Follow-up to this messageBrian 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?
Post Follow-up to this messageIn 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 ***
Post Follow-up to this messageBarry 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.
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.