Subject: New Drafts

From: James Kempf <[email-masked]>
Date: Thu, 21 Dec 2000 11:29:30 -0800 (PST)

Just posted the following to the IETF Drafts web site:

draft-kempf-srvloc-notify-05.txt - Port number and extension ids added, major
editing in Section 5.2 to clarify readability, added IPv6 support. This should
about be ready for Experimental.

draft-kempf-2614bis-00.txt - Suggested changes in the SLP API.

Comments welcome.

		jak

---

From: Matt Peterson <[email-masked]>
Date: Thu, 21 Dec 2000 14:14:09 -0700

Comments on draft-kempf-2614bis-00.txt:

I am especially pleased to see a new declaration for SLPGetProperty()! 
However, since you asked for comment, I wonder if it would be also be
possible to consider the following issues that are addressed in OpenSLP
by a slight divergence from RFC 2614 (see
http://www.openslp.org/doc/html/ProgrammersGuide/Divergence.html):

SLP Service URLs are required
------------------------------
SLP Service URL syntax is required for all functions that accept url
strings.  The following is a list of affected functions: 

       SLPReg() 
       SLPDeReg() 
       SLPDelAttrs() 
       SLPFindAttrs() 
       SLPParseSrvURL() 
       SLPSrvURLCallback() 

The decision to require SLP Service URL syntax was made based on in part
the following scenario: 

Suppose that two calls were made to SLPReg() with a srvurls and srvtypes
of "192.168.100.2","http" and "192.168.100.2","ftp".  Now the developer
wants to deregister one service with out deregistering the other. How
can it be done?  The SLPDeReg() call does not have a service type
parameter so it would be impossible for the underlying implementation to
distinguish between the two registrations.  In an attempt to
standardize, OpenSLP expects valid Service URLS.

OpenSLP requires strict Service URL syntax so that a Service URL can be
treated as a unique "database key" that identifies a registered
service.   Not requiring Service URL syntax allows for several
ambiguities like the one mentioned above. 

Scopelist may be the empty string ("") or NULL
----------------------------------------------
In the calls where a scope list is accepted as a parameters, RFC 2614
says that this parameter may not be the empty string or  NULL.   OpenSLP
allows scope list to be NULL or the empty string.  If the empty string
is passed in as a scopelist, then OpenSLP will use the scopelist the
system administrator has configured for the machine.  This saves 99% of
all developers the time of calling SLPFindScopes() and parsing the
result. 

Scoping is almost entirely an administrative task.  Having to deal with
and understand scopes will be a burdon to the large majority of
programmers.  Unless they are writing some sort of SLP browser, they
will be very content to use the scope that the machine is configured to
use. 

Incremental registrations an de-registrations
---------------------------------------------
The only reason I can think of ever wanting to expose the functionality
of incremental registration and deregistration is to represent dynamic
data via SLP attributes.  I can think of a long list of reasons why this
is a very very bad idea.  With out doubt, it is best to instruct SLP
developers to minimize, when ever possible, the number of calls that
ultimately generate SrvReg and SrvDereg messages.  If dynamic data is to
be represented, it is best do do it via a specialized protocol optimized
for the given service.  OpenSLP does not support incremental
registrations and de-registrations via SLPReg() and SLPDelAttrs()
because we have found that when developers learn what really happens
"under the SLP covers" they are very carefull *not* to call them very
often. 

In addition to poor usage of network resources, incremental
registrations and de-registrations require additional code that
decreases the efficiency of and increases the size, and complexity of
API and agent implementations.

Possible addition of a *VERY SIMPLE* Attribute parsing function
---------------------------------------------------------------
The following function is secretly included with OpenSLP and has proven
to be very useful:

SLPError SLPParseAttrs(const char* attrstr,
                       const char* id,
                       int* valsize,
                       const char** val);
/*                                                                        
*/
/* Used to get individual attribute values from an attribute string
that   */
/* is passed to the
SLPAttrCallback                                        */
/*                                                                        
*/
/* attrstr  (IN) the attribute string as passed to
SLPAttrCallback         */
/*                                                                        
*/
/* id       (IN) the ID of the attribute you want the value
for            */
/*                                                                        
*/
/* valsize  (OUT) the size in bytes of the attribute value.  May be
zero   */
/*                if the ID was not
found.                                 */
/*                                                                        
*/
/* val      (OUT) the attribute value of the requested attribute.
Maybe    */
/*                null if ID was not found. The returned pointer
points    */
/*                back into the original attrstr. Do not free the
returned */
/*                pointer.  val WILL NOT BE NULL TERMINATED.  IF YOU
WANT  */
/*                A NULL TERMINATED STRING malloc() valsize+1 bytes
of     */
/*                memory, memcpy() val and null terminate the
buffer       */
/*                                                                        
*/
/* Returns: Returns SLP_PARSE_ERROR if an attribute of the specified
id    */
/*          was not
found                                                  */

NULL and empty string are acceptable parameters
-----------------------------------------------
According to RFC 2614, NULL is not exceptable value for any parameter. 
Instead programmers are instructed to pass the empty string "".  OpenSLP
allows programmers to use either NULL or the empty string.   It is very
easy to deal with both NULL or empty string in the implementation, and
allows developers to write more familiar and slightly more efficient
code.  There should not be any reason why the compiler should be
required to pass a pointer to a static constant empty string when NULL
will do just a well.   This is why the vast majority of C APIs use NULL
to indicate an ignored parameter or default value -- not the empty
string (""). 

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

---

From: Erik Guttman <[email-masked]>
Date: Fri, 22 Dec 2000 17:23:10 +0100 (MET)

Matt wrote:  

MATT> SLP Service URLs are required 
MATT>------------------------------ 
MATT> 
MATT> Suppose that two calls were made to SLPReg() with a srvurls  
MATT> and srvtypes of "192.168.100.2","http" and "192.168.100.2","ftp".  
MATT> Now the developer wants to deregister one service with out  
MATT> deregistering the other. How can it be done?  The SLPDeReg()  
MATT> call does not have a service type parameter so it would be 
MATT> impossible for the underlying implementation to distinguish  
MATT> between the two registrations.  In an attempt to standardize,  
MATT> OpenSLP expects valid Service URLS. 

We would like to leave it open for people to use other URLs than
service URLs - for instance - http://192.168.100.2 and ftp://192.168.100.2
in your example would not be ambiguous.

MATT> I see how a 1 to 1 mapping between url and type resolves my 
MATT> concern, but what I don't understand is how any sort of 1 to 
MATT> 1 mapping between url and type can be enforced.  
MATT> 
MATT> For example what should a DA do if it already has a registration 
MATT> as specified above (URL = "ftp://ftp.acme.com" SrvType =
MATT> "service:file-server") and receives another SrvReg with
MATT> URL=ftp://ftp.acme.com and SrvType="service:ftp".  Should the DA 
MATT> add the new registration to its internal database or reject it 
MATT> because it conflicts with another registration (i.e. breaks the 
MATT> one to 1 to 1 correlation between URL and type)?

RFC 2608 is clear about this.  In one case, the FRESH flag is set and
the subsequent registration replaces the first one.

   A registration with the FRESH flag set will replace *entirely* any
   previous registration for the same URL in the same language.  If the
   FRESH flag is not set, the registration is an "incremental"
   registration (see Section 9.3).

In the other case, FRESH is not set and:

   The SA MUST use the same <service-type> in an update message as was
   used in a prior registration of the same URL. If this is not done,
   the DA returns an INVALID_UPDATE error.

MATT> OpenSLP requires strict Service URL syntax so that a Service URL 
MATT> can be treated as a unique "database key" that identifies a 
MATT> registered service.   Not requiring Service URL syntax allows 
MATT> for several ambiguities like the one mentioned above. 

In reply, Jim wrote:
JIM> I believe RFC 2608 requires that there be a one to one mapping 
JIM> between a service type and a service URL. This would forbid having 
JIM> one URL that is a service: URL and one that is not registered under 
JIM> the same service type name, so there would be no ambiguity w.r.t. 
JIM> SrvDereg.

Jim is right, but there are ambiguities still.

There are 3 things which are somewhat conflated in SLP:

1 - Service Type - used for searches (a wildcarding technique)
2 - Service Locator - the URI of the service
3 - Service Instance - the unique id of the service

In SLP, we use 2 to mean both 2 and 3.  1 is simply used as a search
key.  We use 1 only where 

 - we are registering (to put the new service entry in the right index)
 - updating (reregistering) to make sure that we are updating the right 
   indexes - if a subsequent SrvReg has an inconsistent service type 
   field we return a INVALID_UPDATE error
 - SrvRqst message uses the service type string to access the right
   service index
 - SrvTypeRqst gathers all the service type string index fields (useful
   only for top level browsers)

This leads to two questions:

 I. Why doesn't SLPv2 include a service type field in SrvDeReg?

    Because SrvDereg affects an entire service, which by definition
    can have only one service type associated with it.  Having the
    SrvDeReg include a service type string would increase the chance
    of sending incorrect SrvDereg messages and add no functionality.
    Thus, we did not include the string.

II. Why is the locator also the unique service ID?

    It seemed simpler at the time.  In retrospect we created a number
    of problems.  (1) One locator (like a http: or mailto: url) can
    be used for many 'services'.   This is commonly the case when
    the http or mail service is actually a *gateway.*  (2) One service
    can have multiple locations, like a server which has multiple
    addresses (hence multiple URLs).

This analysis got long so I put it into another mail message to start
a new thread of discussion.
            
MATT> Scopelist may be the empty string ("") or NULL
MATT> ----------------------------------------------
MATT> In the calls where a scope list is accepted as a parameters, RFC 2614
MATT> says that this parameter may not be the empty string or  NULL.   OpenSLP
MATT> allows scope list to be NULL or the empty string.  If the empty string
MATT> is passed in as a scopelist, then OpenSLP will use the scopelist the
MATT> system administrator has configured for the machine.  This saves 99% of
MATT> all developers the time of calling SLPFindScopes() and parsing the
MATT> result.  

As long as the API is clear about it and that it does NOT mean use
the empty string (with all its SLPv1 connotations), then I am fine
with this suggestion. 

> will be very content to use the scope that the machine is configured to

I agree with you.  Scopes should not concern the user of the API 
unless specific subsets of the scopes list are to be used - for 
example, for targetting a request to a particular scope.  

MATT> According to RFC 2614, NULL is not exceptable value for any parameter. 
MATT> Instead programmers are instructed to pass the empty string "". 

OK.  In practice, one has to check for NULL anyway, since it is so 
commonly done, as you say.  I see both sides of this issue.

On the one hand, I understand Jim's point about it being easier to 
check for illegal values, on the other I have used many friendly 
APIs which allow NULL to be used as the default.
 
MATT> Incremental registrations an de-registrations
MATT> ---------------------------------------------
MATT> In addition to poor usage of network resources, incremental
MATT> registrations and de-registrations require additional code that
MATT> decreases the efficiency of and increases the size, and complexity
MATT> of API and agent implementations.

If we deprecate these features in SLPv2bis - then we can eliminate them
from the API, too.  

If you want to do incremental registration you can always just reregister 
the entire service.  The only time this would result in excessive use of
the network is if the service advertisement included attributes which 
were really big (for instance, if the advertisement includes an attribute
with a binary encoded value of a small icon for a GUI, etc.)  This 
necessitates retransmitting it whenever *any* attribute is changed.

MATT> Possible addition of a *VERY SIMPLE* Attribute parsing function
MATT> ---------------------------------------------------------------

This is OK by me, as long as the caller is willing to accept 
SLP_NOT_IMPLEMENTED, as with other helper functions.  This is
because some very small implementations may not be able to
implement the entire API.

I agree with Jim that we should return NULL terminated strings.

Erik

._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._.
E r i k   G u t t m a n         SHORT msgs: [email-masked]
Sr Staff Engineer, Sun Microsystems       Email: [email-masked]
Eichhoelzelstr. 7, 74915 Waibstadt Germany    Phone: +49 172 865 5497

---

From: Matt Peterson <[email-masked]>
Date: Fri, 22 Dec 2000 09:54:33 -0700

Erik,

See interspersed comments below:

>    the DA returns an INVALID_UPDATE error.

Aha!  Got it now.  This was the clarification I was looking for.  I
believe OpenSLP behaves correctly in this case.

> a new thread of discussion.

I'll re-state in the new thread when I get it, but other than a slight
divergence from RFC 2614 is there any reason why the solution we have
chosen (of requiring Service: scheme urls) is not acceptable?  

> the empty string (with all its SLPv1 connotations), then I am fine

Right.  It would mean use the DHCP, property, or administratively
configured scope.
 
> If we deprecate these features in SLPv2bis - then we can eliminate them

I think it would be wise to deprecate incremental registrations and
de-registrations.  As I mentioned before they suggest that it is OK to
represent dynamic data in SLP attributes and that incremental
registrations may somehow magically circumvent the network traffic that
will be require to propagate changes to DAs (which BTW gets *really bad*
when multiple DAs exist and/or DA to DA communication is implemented).

> the entire service.  

This is the documented workaround in OpenSLP docs.

> The only time this would result in excessive use of

When properly informed, I think that developers will be *very* careful
not to use large attributes -- after all agents do not have to support
TCP.  SLP messages that fit into a UDP datagram are always acceptable. 
I think developers are and will continue to aim for simplicity in the
types of data that will be represented in SLP attributes.  I believe
correct approach is to put complexity into the service-specific
protocols and limit use SLP for what it was designed for - service
location.

Does continued discussion of incremental reg/dereg need it's own thread?

> implement the entire API.

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