Subject: Re: SLP questions

From: James Kempf <[email-masked]>
Date: Mon, 16 Apr 2001 12:59:23 -0700 (PDT)

>  1) It looks like the functionality spec'd by RFC2614 is mainly 
>     suited to UAs.  I see that there are API calls for SAs to use
>     as well (like SLPReg), but it does not look like there are sufficient
>     calls to support all of the things that an SA must support.
>     Is this correct?  
>

The intent of 2614 was to support both SAs and UAs. What do you think
is missing?

>     It looks as though the API offers calls to initiate actions, but don't
>     SAs also have to respond to requests initiated by UAs?  
>     Mainly, I don't see how the API offers up the functionality for an SA
>     to reply to UA requests (like SrvRqst).
>     Am I just missing something?
>

Responding to a UA request is automatic, and the response does
not differ according to the service, i.e. it is completely
and precisely specified by RFC 2608. Therefore, it is handled
entirely under the covers by the library.

>  2) Here's what I want to do:
>
>       - Implement an embedded SA.
>       - The embedded SA will register a standard service type.
>
>     From looking at the OpenSLP stuff, looks like the slpd is a good
>     starting point for an embedded SA.  Are there certain configuration
>     parameters that I need to set so that the slpd acts as an SA only,
>     and does not look like (or act as) a DA on the network?
>

The configuration parameter net.slp.isDA must be set to false in
the configuration file. But if you are doing an embedded SA, typically
there will be no configuration file because the configuration
will be baked in.

>  3) For an embedded SA, I suspect that having an slp.reg (Serialized
>     Registration File) file is not an issue, since I'll be directly 
>     supporting a standard service type.
>     Does that make sense?
>

Yes.

>  4) With regard to the slp.conf file (Configuration File Format), I'd treat
>     it differently.  Instead of having the slp.conf file exist as the text
>     file living on a disk system, it'd be parameters stored in non-volatile
>     RAM that are configurable via a gui (like via a browser).
>     Is that an issue, and is it a reasonable approach?
>

Yes, that's perfectly reasonable, and the answer to 2) above.

>     Also, do all of the parameters in slp.conf need to be user configurable? 
>     Can't I default many of them, and chose the parameters that I want
>     to be user configurable?  Or, do all of the Configuration File
>     parameters need to be user settable?
>

As mentioned about net.slp.isDA, you could bake this one in and not
have it be user configurable. RFC 2614 describes the most general
case.

Hope this helps.

		jak

---

From: Timothy S Zurcher <[email-masked]>
Date: Mon, 16 Apr 2001 13:58:05 -0700

James,

  I'll answer "inline" below.

Matt Peterson,

  Based on the replies from James, and my followups below, there are
  some questions that you might be able to answer.

I hope you folks don't mind the cross list traffic on these questions,
as it proves very useful to me.  This is where the theoretical and
practical meet.  That is, trying to do a real world implementation of
the RFCs that have been published.  I am grateful to both.

Thanks,
Tim Zurcher

>The intent of 2614 was to support both SAs and UAs. What do you think

James,

  I think you helped answer below.  It's the "under the covers by the 
  library" that got me confused.  Indeed, it was "responding to the UA
  requests" that I did not see covered in the API.

  I'm guessing that the API library implementation assumes that an 
  "SA Server" is running, and that the API database is tied into the 
  "SA Server" database.  Therefore once the SLPReg() has been done to 
  register a service, the "SA Server" can handle the replies.  
  Is this what you're saying?

Matt, 

  I've not seen an architectural diagram of what's been implemented in
  the OpenSLP distribution.  I've been attempting to get straight just
  what each piece (common, libslp, libslpattr, slpd) of the distribution 
  supports, and what the overall architecture looks like.  

  Based on the above, is the slpd the "SA Server" I referenced above?

  Is the piece of code that I write to register a specific service 
  distinct from the slpd?  If so, based on the common OpenSLP libraries,
  does it tie into the database used by the slpd?  That is, does it fit the 
  architecture described above?

>entirely under the covers by the library.

OK, see above.

>there will be no configuration file because the configuration

Great.

>have it be user configurable. RFC 2614 describes the most general

Yes, your replies have helpd.

---

From: Matt Peterson <[email-masked]>
Date: Tue, 17 Apr 2001 10:23:21 -0600

Hi Timothy,

>   architecture described above?

Let me answer your questions as they relate to the OpenSLP
distribution.  This will probably be a long email and I am CCing the
lists because I get similar questions all the time.  Keep in mind, what
I write here is based on the CVS HEAD OpenSLP code (soon to be released
as ver 0.9.0).   Here goes...

OpenSLP consists of two binaries: libslp and slpd let me write about
these first.  We will detail the source code layout later.

libslp (the SLP API library)
----------------------------

libslp is the RFC 2614 SLP API implementation.  Developers that are
writing SLP enabled applications will need include slp.h and link to
libslp.  As of OpenSLP 0.9.x libslp will be a *complete* implementation
of the SLP API it will include *all* features described by RFC 2614 with
very few noted exceptions (see
http://www.openslp.org/doc/html/ProgrammersGuide/Divergence.html for
details).

There are four major code paths in libslp.  I like to call them the
"query" code path, the "registration" code path, the "utility" codepath,
and the "initialization" code path

The "query" code paths are entered when a developer calls SLPFindSrvs(),
SLPFindAttrs(), SLPFindSrvTypes(), or SLPFindScopes().  The following
tasks are completed by libslp: First, we build the the appropriate SLPv2
message (SrvRqst, AttrRqst, or SrvTypeRqst).  Second, we locate a DA. 
This can be done via IPC to slpd (if it is running) or via active DA
discovery multicast.  If a DA is located that supports the desired
scope, then the request message is send directly to the DA.  If not,
then the request is multicast or broadcast.  Finally, the library waits
for the SrvRply, AttrRply, or SrvTypeRply.  Retransmissions of the
request, timeouts, and calls to the SLPSrvURLCallback(),
SLPAttrCallback() and SLPSrvTypeCallback() functions are handled
appropriately. 

The "registration" code paths are entered when a developer calls
SLPReg() or SLPDereg().  The following tasks are completed by the
library:  First we build the appropriate SLPv2 message (SrvReg or
SrvDereg).  Second, we MUST locate an slpd running locally or a DA
running remotely.  If slpd is found to be running locally, we send it
the SrvReg or SrvDereg message via IPC.  If slpd is not found, we
multicast for a DA if a DA is found we send it the message via TCP.  If
neither slpd or a remote DA is found, then the library returns an
errorcode to the caller.  

The "utility" code paths is entered when the developer calls
SLPParseSrvURL(), SLPGetProperty() or SLPSetProperty(), etc.  The libslp
code for these functions is not very complex and only changes library
data that is specific to the running process.

The "initialization" code paths are entered when the developer makes a
call to SLPOpen() or SLPClose().  libslp keeps track of the number of
open handles and makes an attempt to cache information that makes SLP
API calls more efficent.  For example, when a call to one of the "query"
or "registration" code paths requires DAs to be discovered, libslp
caches this information.  The known DA cache can then be used for
subsequent calls with out having to multicast every time.  The reason
for mentioning this is because the library cleans up and frees all
cache-like resources when the open handle count reaches 0.

slpd (the OpenSLP daemon)
-------------------------
slpd is a daemon or service that runs all the time.  It is recommended
that slpd run on all hosts that will be running SLP enabled
applications.  It is *highly* recommended that slpd run on hosts that
register serviced (use the "registration" code path in libslp).  Slpd
has three main purposes: hold registrations, keep track of DAs, and act
as a DA.

The main reason for needing a SLP daemon (slpd) to hold registrations is
that SLP message requests are sent (via UDP or TCP) to port 427.  On
most operating systems, only the super user (root) can bind to a
reserved port.  In addition, having a seperate process that holds
registrations, slpd greatly reduces maintenance overhead for SLP enabled
applications.  With out slpd, applications that linked with libslp would
have to be run as root (to bind to port 427), and the library would have
to be a nasty mess of threads (a thread would have to wait for requests
and call callbacks).

If you are getting the idea that SA functionality is sort of divided
between libslp, and slpd, then you are on the right track.  As mentioned
before, libslp is the entity that actually creates the SrvReg message. 
Slpd receives the SrvReg message via IPC and uses information from it to
respond to SrvRqst, AttrRqst, and SrvTypeRqst messages.  

Currently, in OpenSLP the IPC mechanism is nothing more complex than the
loopback.  Slpd binds to port 427 on all interfaces including loopback. 
The SrvReg and SrvDereg messages sent by the "registration" code paths
in libslp are sent to port 427 of the loopback address.  Using the
loopback in as an IPC mechanism is an attempt to reduce redundant code
required to utilize another IPC mechanism, as well as an attempt to keep
OpenSLP very portable.

Slpd also has the job of keeping track of known DAs.  On initialization,
slpd performs an active DA discovery (as described in RFC 2608).  Slpd
also listens for passive DAAdverts and for dying DAAdverts so that it
always has "real-time" information about DAs that exist.  This
information is passed to  libslp (via the loopback IPC) when requested,
but more importantly, it is used to make sure that service registrations
are propogated to the appropriate DAs.  In otherwords, If slpd gets a
SrvReg from libslp (via the loopback), it records it in its own database
then forwards it on to DAs that support the scope of the registration.  

Finally, in addition to performing the tasks described above, slpd can
operate as a fully functional (RFC 2608 compliant) DA.  The net.slp.isDA
setting of the slp.conf file controls this the DA functionality.  

OpenSLP source code
--------------------
The OpenSLP source code is divided into 9 peices.  Each of the divisions
is represented by a top level directory in the distribution tarball. 
They are the following: common, slpd, libslp, libslpattr, slptool, test,
etc, doc, and win32.

The "common" code is code that is used by both libslp and slpd.  The
common code contains the following functionality: String compare
routines, common linked list and buffer data structures, message
descriptor data structures and message parsing code, SLP "property"
code, and  authentication and cryptography abstractions.

The libslp code is specific to the SLP API implementation.  It is
organized so that each API is implemented in a seperate .c file with
several .c files to provide "cross API" functionality.  The libslp code
(along with related common code) is probably the most approprate code
for people to use for writing embedded SLP UA implementations.  The
libslp code (combined with related common code) knows how to create and
send all SLP requests and how to parse all SLP replies (using both TCP
and UDP transport).

The slpd code is very specific to the slpd daemon.  It is organized in
on boundaries of major functionality.  slpd has a fairly complex
non-blocking, non-threaded, and single process design.  The design is
easy to port "out of the box" to other OSes since it does not rely on
the OS specific threads or fork() behaviors.  Unfortunately, it is a
little hard to understand.  

The slpd code can be roughly divided into 4 chunks.  The main peice is
the network engine which handles reception and sending of SLP message
buffers.  The processing and parsing code interprets message buffers and
generates message buffer replies.  The other peices are the service
database which stores stores registrations, and the known DA database
that stores information about DAs.  

The network engine consist of a main select() loop and various incoming
and outgoing socket handling functions.  Developers that are familiar
with sockets programming should be able to understand things if they
remember that incoming sockets are sockets that were accept()ed by slpd
and outgoing sockets are those that are connect()ed by slpd.  Socket
type (datagram or stream) and socket states (connected, reading,
writing, etc.) are used known how to handle select()ed sockets.  The
service database and the known DA databases linked list storages of
SrvReg and DAAdvert information.

The processing and parsing code will be especially useful for someone
writing a specialized or embedded SA.  99% of processing and parsing
functionality functionality is found in two files common/slp_message.c
and slpd/slpd_process.c.  The code from these two files provide
everything you'll need to interpret requests, and generate reply buffers
that could later be delivered via a simpler network engine than the one
implemented in slpd_main.c slpd_socket.c slpd_incoming.c and
slpd_outgoing.c files.

The libslpattr code was not written by Caldera.  It was written by Evan
Hughes as part of a graduate research project.  libslpattr was designed
as a general use SLP attribute parsing library.  OpenSLP uses this
library to support predicate based SrvRqsts and AttrRqsts with tag
lists.  libslpattr is only called by slpd from the slpd_predicate.c file
and is needed if ENABLE_PREDICATES code is built.

slptool is a command line wrapper to the SLP API.  It is included in the
distribution tarball because it is really useful, and also because it
offers a very good example of how to write SLP enabled code using
libslp.

The test directory contains a suite of testing tools that were written
by Evan Hughes and David McCormack.  They are useful as sanity checks as
we make changes to OpenSLP source code.

The etc directory contains sample OpenSLP configuration files.  These
should be copied to the appropriate locations when installing OpenSLP.

The doc directory contains all of the SLP and OpenSLP related
documentation that is available on the www.openslp.org website.  The
most important bit of documentation is the "OpenSLP Programmers Guide".

The win32 directory contains MSVC project files for building OpenSLP on
windows platforms.

I hope that this is helpful to everyone.  Please feel free to send me
email or post to openslp-devel if you have more questions.

-- 
Matthew Peterson
Sr. Software Engineer
Caldera Systems, Inc
[email-masked]