home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!charon.amdahl.com!pacbell.com!ames!olivea!spool.mu.edu!umn.edu!mmm.serc.3m.com!mmc.mmmg.com!timbuk.cray.com!shamash!easyaspi.udev.cdc.com!gsa
- From: gsa@easyaspi.udev.cdc.com (gary s anderson)
- Newsgroups: comp.protocols.tcp-ip
- Subject: Re: rpc process chewing up resources
- Message-ID: <49395@shamash.cdc.com>
- Date: 6 Nov 92 22:08:11 GMT
- References: <DERAADT.92Nov5044404@newt.newt.cuc.ab.ca>
- Sender: root@shamash.cdc.com
- Reply-To: gsa@easyaspi.udev.cdc.com (gary s anderson)
- Lines: 165
-
- In article <DERAADT.92Nov5044404@newt.newt.cuc.ab.ca>, deraadt@newt.cuc.ab.ca (Theo de Raadt) writes:
- |> I'm currently implimenting YP client functionality for 386bsd. So far,
- |> it's been an enjoyable and frustrating time....
- |>
- |> In article <49256@shamash.cdc.com> gsa@easyaspi.udev.cdc.com (gary s anderson) writes:
- |> > |> > |> > sits within the "yp" library code (you need to ask SUN why "pinging"
- |> > |> > |> > the portmapper from within "yp" is useful). This has the wonderful
- |> > |> > |> Hmmmph!
- |> > |> > |> What would you do if you wanted to discover if ypbind is running?
- |>
- |> Well, on some systems (including my code at the moment) that's exactly
- |> why TCP is used. It's faster than UDP.
-
- Please explain how TCP is "faster" than UDP. You are sending one request
- and getting one reply. This is an unfragmented request/reply sequence,
- in the case discussed in this thread. TCP adds an end-to-end
- connect sequence besides sending the request and receiving the response.
- I'd like to know which systems you use which can create a connection
- and send a message faster than you can just send the message.
-
- There are many reasons to use TCP but your comment on "faster"
- is obviously missing some relevant context information.
-
- |>
- |> My first code used UDP to find out if ypbind was running. Well, if you
- |> don't get an answer, even in talking to 127.0.0.1, well, the kernel's
- |> buffers could just be swamped at the moment. So you have to try a few
- |> times. Not pretty.
-
- If there are no kernel buffers you can't create a TCP connection
- either. The case where UDP suffers is when concurrent request
- information overflows the receive socket. In the case we are
- talking about this isn't a major concern (i.e. small packets and
- short think time in server. Additionally, vendors selling useful
- multi-user systems provide reasonable buffer sizes). Consequently,
- overflowing the TCP connect limit would be roughly
- equivalent to the UDP receive buffer limit.
-
- NOTE - In case you missed, the TCP connection in question is directed
- to the portmapper not to ypbind.
-
- |>
- |> So, I started using TCP. Immediate response yes/no whether YP is
- |> running. I had no real concerns with whether the portmapper is
- |> running.
- |>
- |> I'm have a Sun too. A few minutes ago, I went and looked to see why
- |> the file /etc/ypbind.lock exist... a bit of snooping and following a
- |> hunch...
- |>
- |> 4835 -rw------- 1 root 0 Nov 2 21:46 /etc/ypbind.lock
- |> ^^^^
- |> inode
- |>
- |> pstat -i | grep 4835
- |> f23f9a8 R 7, 0 4835 100600 1 0 0 E 2 0 1 VREG
- |> ^^^
- |> That little 'E' is an exclusive lock.
- |>
- |> Could someone explain exactly what is going on here? What I suspect
- |> follows: ypbind maintains the exclusive lock on /etc/ypbind.lock
- |> Processes that are interested can find out if ypbind is running by
- |> doing a lockf(fd, F_TEST). Sun's ypbind also puts an exclusive lock
- |> on /var/yp/binding/domainname.2 and /var/yp/binding/domainname.1. I
- |> suspect the 2 is YPBINDVERS.
- |>
- |> Just trying to get a flock() on that file seems to work. This is so much
- |> easier than what it appears the entire argument here is about.
- |>
- |> Here's what happens if I trace a program that needs to check YP.
- |>
- |> open ("/var/yp/binding/cuc.ab.ca.2", 0, 036736173730) = 4
- |> flock (4, 06) = -1 EWOULDBLOCK (Operation would block)
- |> mmap (0x8ab8, 14, 0x1, 0x80000001, 4, 0) = 0xf7710000
- |> close (4) = 0
- |>
- |> Aha. The fact that the flock() failed tells us that ypbind is running.
- |> Sun places into the binding file the actual (struct sockaddr_in) at
- |> which the current ypserver can be found (It could be ypbind's address,
- |> but it makes more sense to be ypserv's address). So they mmap() the
- |> (struct sockaddr_in) and continue.
- |>
- |> > |> >
- |> > |> > I would send a UDP RPC request to the portmapper to find out
- |> > |> > if ypbind was registered. The problem is that there is code
- |> > |> > which creates a "dummy" TCP connection just to see if the
- |> > |> > portmapper is running (i.e. doesn't trust UDP time-outs as
- |> > |> > sufficient evidence that the portmapper is not running).
- |>
- |> I would not trust a UDP timeout on "localhost" as meaning that the
- |> portmapper is dead. It might take 5 seconds for a busy portmapper to
- |> answer. Someone in Timbuktu, at the end of a very slow link, may have
- |> been spraying the portmapper. Packets may have convoyed, and the
- |> portmapper may be swamped! How long are you going to wait around?
-
- Why do you assume that this same phantom you fear cannot spray the
- portmapper with bogus TCP connections? You will find that the same
- quantity of bogus TCP connections are generally worse than bogus UDP
- packets. People with this level of paranoia typically deploy firewalls.
-
- Also, you seem to be disillusioned about what happens when a TCP
- packet gets dumped on the ground. You will note that it has a
- regressive back-off timer with the lowest retry level at
- approximately one second. What TCP gives you is a well-respected
- retry algorithm which may not always be present in various UDP
- applications.
-
- The advantage that was hypothesized for TCP (in this particular
- thread) is that the UDP/ICMP "port not available" (i.e. no server currently
- bound to the specified port) may not be as well supported as the
- equivalent TCP RST functionality. If your application has some
- semantical benefit gain from this feature then TCP might be
- a better choice.
-
- |>
- |> > |> > If the connection succeeds, it is immediately closed and then
- |> > |> > the UDP RPC request is made to the portmapper to get the
- |> > |> > information about ypbind.
- |> > |>
- |> > |> Perhaps my point was not clear.
- |> > |>
- |> > |> By using TCP you avoid having to wait for a UDP time-out to expire when
- |> > |> things are not present. Which would make you more unhappy? Having an
- |> > |> anonymous TCP port number tied up for a little while or having to wait
- |> > |> a large part of a second (or more if you allow remote access over slow
- |> > |> links) to discover that the portmapper is not running?
- |>
- |> With TCP, your connection will succeed immediately, well, as long as
- |> the listen queue has room for you....
- |>
- |>
- |> Really, I prefer Sun's method of checking for yellow. A flock() on a
- |> locked file means you are talking to an inode that is already in the
- |> buffer cache. That's got to be faster and more reliable than talking
- |> to portmap & ypbind.
-
- As long as everything is local you can reliably use files for
- interlocking, however, I would not be overly enthused to see rpc.lockd
- as the cornerstone for provision of these services (e.g. you ever needed
- to solve a remote concurrency issue).
-
- |>
- |> Anyways, I'm going to impliment my routines much like Sun's did!
- |>
- |> Only one thing bothers me with the RPC programming I am doing. Sun's
- |> ypbind is not multithreaded; rather, it forks when it gets a request
- |> for a currently unbound domain. I decided to make my ypbind much more
- |> multithreaded. What I have come to discover to my disgust is that if
- |> you wish to write a properly multithreaded RPC application you have to
- |> give up all the juicy RPC and SVC routines and dig right into the XDR
- |> level. What a pain. And, boy, I could scream because I have found no
- |> way to access msg->msg_xid from the SVC/RPC level! For a proper
- |> multi-threaded application, you are going to need to save a copy of
- |> that for the later reply!
- |> <tdr.
- |> --
-
-
- One technique is to use request-only primitives (e.g. use timeout==0) to satisfy
- multi-threading needs. However, since you probably want to interoperate
- with existing ypbind entities this probably won't help much.
-
-
- |>
- |> This space not left unintentionally unblank. deraadt@newt.cuc.ab.ca
-