Service Location Working Group Erik Guttman Internet Draft Sun Microsystems, Inc. Expires in six months An API for Service Location This document is an Internet-Draft. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as ``work in progress.'' To learn the current status of any Internet-Draft, please check the ``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or ftp.isi.edu (US West Coast). Abstract The Service Location Protocol coupled with the Service Location API provide a new way for clients to dynamically discovery network services. It is simple to offer highly available services which require no user configuration or communication with network administrators prior to use. The document includes examples and applications. Client software modified to use Service Location can make very simple requests to find service by type or by characteristic. The latter capability allows the client to choose intelligently between services of the same type. Service software modified to use Service Location may dynamically advertise its characteristics and existence. Guttman [Page 1] Internet Draft An API for Service Location 25 November 1996 Table of Contents 1. Introduction 2. Glossary 3. Interfaces 3.1. SL_Open 3.2. SL_Close 3.3. SL_Register 3.4. SL_DeRegister 3.5. SL_GetScopes 3.6. SL_GetServiceTypes 3.7. SL_GetService 3.8. SL_GetAttrs 3.9. SL_Free 4. API programming notes 4.1. Multithreading Issues 4.2. Nonstandard Service Types are easy 4.3. Typical Client Scenarios 4.4. Top level information 4.5. Example applications of SLP 4.5.1. Coarse dynamic load balancing 4.5.2. Mobile user finds the nearest printer 4.5.3. Providing highly available services 5. API implementation issues 6. Language specific API specification and examples 6.1. SLP API C bindings 6.1.1. Header file definitions 6.1.2. Interface clarification 6.1.3. Examples 6.2. SLP API Java bindings 6.2.1. Class definitions 6.2.2. Examples 6.3. Syntax for string parameters 6.3.1. Query Syntax 6.3.1.1. List Query Syntax 6.3.1.2. General Query Syntax 6.3.2. Attribute Registration List 6.3.3. Attribute Deregistration List 6.3.4. Attribute Selection List Syntax 6.4. Interpretation of SLP error values 7. Security Considerations 8. Internationalization Considerations 8.1. Character Set identification and use 8.2. Language identification and translation 9. Bibliography 10. Author's Address 1. Introduction The Service Location API allows client and service programs to be modified in a very simple manner to provide dynamic service Guttman [Page 2] Internet Draft An API for Service Location 25 November 1996 discovery and selection. The underlying protocol makes use of strings extensively, as does the interface. String syntax for the List Query, General Query, Attribute Deregistration List and Attribute Registration List and Attribute Filter List are defined below, in the appropriate sections. The API bindings are given in C and Java. The semantics are discussed in a language and implementation neutral way, with these details left to later sections. Applications which are modified to use this API will be source compatible with different SLP framework implementations. 2. Glossary Service Location Protocol (SLP) The underlying protocol allowing dynamic and scalable service discovery. This protocol is specified in the Service Location Protocol [SLP]. SLP framework When a 'Service Location framework' is mentioned, it refers to both the SLP implementation and interface implementation; ie. whatever provides the SLP functionality to user level programs. Directory Agent (DA) A service which automatically gathers service advertisements from SAs in order to provide them to UAs. User Agent (UA) This is the Service Location process or library which allows SLP requests to be made on behalf of a client process. UAs direct requests to DAs when they exist automatically when they exist. In their absense, UAs make requests directly from SAs. Service Agent (SA) This is the Service Location process or library which allows service software to register and deregister itself with the SLP framework. The SA SHOULD also respond to UA requests directly in the absense of DAs. Service advertisement Guttman [Page 3] Internet Draft An API for Service Location 25 November 1996 A service: URL possibly combined with service attributes. When a service 'makes' a service advertisement, it uses the SL_Register API. This distributes the service advertisements to Directory Agents and in the SLP framework. The service: URL A service of a particular type announces its availability with a service: URL which includes its service access point (domain name and possibly its port number) and optionally basic configuration parameters. Service Attributes The attributes associated with a given service. The values that can be assigned to service attributes are defined by the Service Type template. Service Type template A document which describes the syntax of the service: URL for a given Service Type, the protocol the client will use to make use of the service and a definition of all service attributes: the meaning, defaults, constraints of each value the attributes can take on. Each Service Type is identified by a string (usually the same name as the protocol used to deliver the service.) See "The service: URL Scheme" [SRV]. Scope A string used to control the availability of service advertisements. Scopes are assigned by site administrators to group services for many purposes, but chiefly as a means of scalability. DAs assigned a scope will store only services advertised with the same scope value. UAs SHOULD use a scope string in requests whenever possible. Closure The set of attributes supported by all the services in a network of a particular type. For instance, the collected attributes of all printers may be obtained. Closures are used to discover the range of possible values for services. Service queries are constructed by selecting combinations of desirable characteristics from this range. Naming Authority (NA) This is a 'suffix' to the service type string. It completely changes the meaning of the service type. NAs are used for private definitions of well known Service Types and Guttman [Page 4] Internet Draft An API for Service Location 25 November 1996 experimental Service Type extensions. The default NA is "IANA", which may be omitted. 3. Interfaces Of the interfaces listed below, three are for use only in a C API: SL_Open, SL_Close and SL_Free. The first two interfaces are unnecessary in an object oriented interface, as the object initialization and finalization code will perform all the needed resource allocation and freeing. Further, the object providing SLP interfaces will encapsulate preference variables. SL_Free is included solely as a convenience, for freeing Result data structures. In an object-oriented language, resource freeing will be handled by the result objects themselves. The C API requires the use of a SL_SrvHandle, which is created by SL_Open and passed into each interface. The analagous entity for the Java API is the ServiceLocator object which encapsulates all the information and functionality that the SL_SrvHandle provides. For Java interface implementors: The semantics of SL_Open and SL_Close must be followed even if SL_SrvHandles are not required. 3.1. SL_Open This interface is used to create a "SL_SrvHandle", which encapsulates the program's default settings set by this call. SL_Open may also be used to modify the settings associated with an existing SL_SrvHandle. SL_Open must be used to generate a SL_SrvHandle before any other API functions are used: The library should be initialized at this point. The settings which are configurable by SL_Open determine how service requests will be issued. They include the Language tag, character set, the maximum time to wait for a response, and whether to "get all services" or just "return the first one found." The SL_SrvHandle is entirely implementation dependent. It is a simple mechanism which allows instrumentation, resource tracking and avoidance of global state. The SL_SrvHandle will also allow the API implementation to refer to some synchronization state, to provide the synchronous and sequential access semantics described in Section 4.1. 3.2. SL_Close This interface closes and frees all resources associated with the SL_SrvHandle. It sets the SL_SrvHandle to NULL. When the last SL_SrvHandle is closed, the library frees all its resources. 3.3. SL_Register Guttman [Page 5] Internet Draft An API for Service Location 25 November 1996 The service supplies a service: URL, and possibly service attributes. The attributes to use, their defaults and interpretation, are all given in the Service Type template. The service also specifies the Lifetime of the service (how long it should remain registered), as well as the Language tag and character set used. A call to SL_Register with a URL which has already been registered will be an 'update'. It will replace the attributes previously registered, if the update contains attributes of the same name, language and character set. For example: If the first registration has attributes "(A=1),(B=2),(C=3)" and the subsequent registration has attributes "(C=30),(D=40)" the registration will end up with "(A=1),(B=2),(C=30),(D=40)". An Attribute Registration list string is used for registration. The above are examples of such strings. Service advertisements may be made multiple times for the same URL, in different languages and different character set encodings. A service program may provide different translations of the services offered in this way. For example, the service could be registered with service attributes translated to English, Russian and Arabic, with the appropriate character sets. The same service: URL may now be obtained by client programs with different user language skills. A service registered without a scope may only be available from DAs which have not been configured with any scopes. UAs must explicitely request services which are unscoped. For these reasons, it is highly recommended that scopes be used if they have been defined for a given site. If a SA crashes, or the program which used the SL_Register function to make a service advertisement exits without calling SL_Deregister, the longest that the stale service advertisement can remain available in the SLP framework is 18 hours. The iLifetime parameter determines how long the registration is valid for. It can take any value from 1-65535 (seconds). If the value is -1, the SLP API implementation will make sure to schedule updates so the service advertisement is continually available. The final parameter, iRefreshHint, may be set to 0 for the 'default' refresh interval. It may also be set at a number (less than the Guttman [Page 6] Internet Draft An API for Service Location 25 November 1996 value for iLifetime). This is a request that the API implementation refresh the service advertisement at a particular interval. For example, if iRefreshHint is 60, the service will be refreshed every 60 seconds. The iLifetime could be -1 (continual). The service will be available continuously: The API will choose some Lifetime on the order of 120 or 180 to ensure this, and refresh it every 60 seconds or so. If the service goes down, the longest the service will be "falsely advertised" is a minute or two. The shorter the iRefreshHint, the less chance the SLP framework will have stale data in the event of a service failure. The shorter the interval between refresh though, the greater the amount of protocol work that needs to be done. 3.4. SL_DeRegister The service: URL of the service to deregister must be provided. If this is the only information provided, the service advertisment will be deregistered in every language and character set it has been registered in . If a Language tag, character set and Attribute Deregistration List are provided the attributes in the Deregistration list will be removed from the service advertisement. 3.5. SL_GetScopes This returns an array of strings with all available scope values. 3.6. SL_GetServiceTypes This returns an array of strings with all available service types. Service Types with NAs will be returned as distinct Service Types, ie. "blah" and "blah.xyz" are not the same. This request may include a Scope. If it does not, it will only return the Service Types of service advertisements made without a Scope. 3.7. SL_GetService This interface takes a Query String. This string includes three parts: Service Type - (can be discovered using SL_GetServiceTypes) Scope - (can be discovered using SL_GetScopes) Query - (can be either a list or general query. The attributes used in the query can be discovered using SL_GetAttrs). The Query portion of the parameter allows the caller to specify Guttman [Page 7] Internet Draft An API for Service Location 25 November 1996 exactly what service advertisement or advertisements are desired. This returns one or more service: URLs, their Lifetime in seconds and address information ready to be used in networking calls. 3.8. SL_GetAttrs If the URL supplied is a complete service: URL, the attribute information returned will be for that particular service. The service type string may include a NA suffix. The syntax for including this is: service-type-with-NA = srvtype-string "." NA-string restricted-string = ALPHA / "+" / "-" srvtype-string = restricted-string NA-string = restricted-string Attributes will only be returned for the service registered with the Scope provided in the SL_GetAttrs call. Finally, the result may be filtered with a Attribute Request Filter string parameter. If this is not supplied, ALL attributes are returned. If it is supplied, only those attributes on the list are. An attribute tag ending in '*' matches all attributes starting with this substring. A Service Type string may be passed in as the URL parameter instead of providing a complete service: URL. In this case, the results which are returned are the attributes for ALL services of the specified Service Type. 3.9. SL_Free This API is only available for a C language interface. This function frees all resources associated with the data passed in. The Result pointer passed in will be modified to be NULL. 4. API programming notes 4.1. Multithreading issues Each SL_SrvHandle (C) or ServiceLocator Object (Java) will only allow one concurrent access at a time. Interfaces are synchronous and will block until they are complete. If a second thread attempts to use the same SL_SrvHandle or ServiceLocator Object to perform a SLP API function which has been labeled as 'synchronous', it will block until the first thread completes its synchronous operation. A multithreaded program may create multiple SL_SrvHandles or ServiceLocator objects to make concurrent use of SLP interfaces. Guttman [Page 8] Internet Draft An API for Service Location 25 November 1996 4.2. Nonstandard Services Types are easy It is trivial to register and discover services of nonstandard types. Simply make up a Service Type string (by convention, nonstandard service types begin with the string "x-"). 4.3. Typical Client Scenarios There are two typical use scenarios: - canned query: Issue a SL_GetService. Try each service in turn in the reply until one works. - browse for a service: Issue SL_GetScopes. Issue SL_GetAttrs for the desired Service Type using the selected Scope. Construct a query string, then use SL_GetService. If the user wishes, call SL_GetAttrs to get all (or some more) attributes for the service returened by the SL_GetService. 4.4. Top level information The SL_GetServiceTypes is used to implement network service browsers and administrative tools. Normally a client application knows what Service Type it will need. Use the Service Template as a guide to designing client query and service profile user interfaces. It can also be used for designing a user interface for system administrators who will define the attributes of a service. Service Templates are themselves a service which can be discovered. See "The service: URL Scheme" [SRV]. 4.5. Example applications of SLP The most common use of SLP will simply be for clients to locate their server by type and attribute. Many distributed applications require discovery at configuration time. The SLP framework provides a lightweight standard mechanism for doing this. Example domains which might benefit are: Client-Server Database systems, network based games, and distributed object systems. Some more sophisticated examples are described below: 4.5.1. Coarse dynamic load balancing One approach to load balancing simply distributes work on a rotating basis among a set of servers. This rotation may be achieved using redirection at various levels. This is a static approach: It has an distribution algorithm which does not change depending on the actual state of the servers. A better approach could be to have the services provide feedback, so Guttman [Page 9] Internet Draft An API for Service Location 25 November 1996 as to allow dynamic load balancing. In this approach, the state of the load of the services themselves determines the amount of work to shift away or to the server. To achive this, services would have to be instrumented so as to provide a "load metric." This attribute could be advertised using SL_Register, updating the current service advertisement. The finest granularity achievable given the timing of SLP would be on the order of seconds. This is why I call the dynamic load balancing "coarse." Clients seeking to dynamically discover a server with the lowest "load metric" would first issue a SL_GetAttrs to obtain the range of the attribute. Then, the SL_GetService function would be used, with the query selecting the lowest load metric value. This would return the service: URL to bind to. 4.5.2. Mobile user finds the nearest printer A mobile user could use SL_GetAttrs to on the lpr service type, requesting all "Location Description" and "Location Address" attribute values be returned. The user is presented with this list and selects the closest location. SL_GetServices is used to obtain the service: URL which has this location attribute. The user may now print and know where to find the result. 4.5.3. Providing highly available services When a vital service needs to be brought down, users often suffer down time. This requires network administrators to communicate with their user community, defer nonessential maintainance and upgrades and to schedule them at off hours. Using Service Location, system administrators would need only start a back up service and bring down the primary server. Client software could simply rediscover the necessary service by type and characteristic, reconnect and proceed. This sounds harder than it would be in practice: The client software would only need to be changed in one respect. The error path which announced the client "lost contact with the server" would be changed. The same code the client used for dynamically discovering the service in the first place would be used again. Only if this rediscovery fails need the software decry its sad disconnection. 5. API implementation issues Results of requests should always be coallated to remove duplicates. This is especially important for the results of SL_GetAttrs and SL_GetTypes when there are no DAs: The request will be multicast to all SAs, and the results will no doubt include duplicate values. Guttman [Page 10] Internet Draft An API for Service Location 25 November 1996 An SA implementation requires as a minimum that service advertisements be registered with a DA. They SHOULD be able to respond to UA queries directly in the absense of a DA. If the latter feature is implemented, the SA will run on the same host, and need some way to service UA requests on behalf of all the hosts services. This SA must listen for TCP requests. Since only one process per host may be bound to a particular TCP port, the SA process will have to be a shared resource and communicate with the different service processes using some form of interprocess communication. There is a subtle bending of the semantics of Service Location if a SA and DA are collocated on the same host. On some socket based implementations of IP multicast, the following occurs: Two sockets are bound to the same UDP port. One of the sockets has joined a multicast group, the other hasn't. A multicast datagram arriving for that multicast group, for the port in question, is delivered to BOTH sockets. Suppose a DA is listening for unicast datagrams on the SLP port, while the SA is listening for multicast packets on the same port. A multicast datagram arrives for the SA, but is delivered to the DA as well. In the worst case, BOTH respond. This will possibly supply redundent information (if the SA services are registered with the DA.) Worse, the DA may reply with information which it 'shouldn't.' None of this is very serious, because the worst that can happen is the UA will receive more information than it would have otherwise. The UA will only receive correct information in any case; it MUST satisfy the UAs request or it won't be returned. 6. Language specific API specification and examples The interfaces presented below are not equivalent, though they both have the semantics described in sections 3, 4 and 5 above. 6.1 SLP API C bindings 6.1.1. Header file definitions /* * The SLP API definition. * */ /*------------------------------------------------------------- * type declarations for service location */ #ifndef SLP_H #define SLP_H Guttman [Page 11] Internet Draft An API for Service Location 25 November 1996 typedef enum { SL_CHAR_ASCII = 3, SL_CHAR_LATIN1 = 4, SL_CHAR_UTF8 = 6 } SL_CharType; typedef enum { SL_TYPE_RESULT = 1, SL_ATTR_RESULT = 2, SL_SRV_RESULT = 3, SL_SCOPE_RESULT = 4 } SL_ResType; typedef enum { SL_STR_VAL = 1, SL_INT_VAL = 2, SL_OPAQUE_VAL = 3, SL_BOOL_VAL = 4 } SL_ValType; typedef struct servicetag { char *s_pcURL; struct sockaddr_in s_sin; int s_iLifetime; } SL_Service; typedef struct opaquetag { int op_iLen; char *op_pcVal; } SL_Opaque; typedef union { int intval; u_char boolval; Opaque opaqueval; char *pcStrVal; } SL_Value; typedef struct attrtag { int a_iNumVals; char *a_pcAttrTag; SL_ValType a_slvaltype; SL_Value *a_pslValue; } SL_Attribute; typedef union { SL_Service i_sl_service; SL_Attribute i_sl_attribute; char *i_pcSrvtype; char *i_pcScope; } SL_ResInfo; typedef struct resulttag { int r_iErrorCode; int r_iAsyncId; int r_iNumValues; int r_iCharEncoding; Guttman [Page 12] Internet Draft An API for Service Location 25 November 1996 char *r_pcLang; SL_ResType r_sl_restype; SL_ResInfo *r_psl_Info; } SL_Result; typedef void* SL_SrvHandle; /*------------------------------------------------------------ * Ease-of-use macros, to enable dereferencing of structures. * * res_srv_url returns the URL of the i'th service * in the service result * res_srv_sin returns the struct sockaddr_in of the * i'th service in the service result * res_srv_life returns the lifetime in seconds of the * i'th service in the service result * res_srvtype returns the string of the i'th service * type in the service type result * res_scope returns the scope string of the i'th * scope result * res_attr_numval returns the number of attr values for * the i'th attr in the attr result. * res_attr_tag returns the tag string for the i'th * attr in the attr result * res_attr_type returns the type for the i'th attr * in the attr result * res_attr_str returns the j'th string value of the * i'th attr in the attr result * res_attr_int returns the j'th int value of the i'th * attr in the attr_result * res_attr_bool returns the j'th boolean value of the * i'th attr in the attr result * res_attr_opaque returns the j'th opaque value of the * i'th attr in the attr result */ #define res_srv_url(i) r_psl_Info[(i)].i_sl_service.s_pcURL #define res_srv_sin(i) r_psl_Info[(i)].i_sl_service.s_sin #define res_srv_life(i) r_psl_Info[(i)].i_sl_service.s_iLifetime #define res_srvtype(i) r_psl_Info[(i)].i_pcSrvtype #define res_scope(i) r_psl_Info[(i)].i_pcScope #define res_attr_numval(i) r_psl_Info[(i)].i_sl_attribute.a_iNumVals #define res_attr_tag(i) r_psl_Info[(i)].i_sl_attribute.a_pcAttrTag #define res_attr_type(i) r_psl_Info[(i)].i_sl_attribute.a_slvaltype #define res_attr_str(i,j) / r_pls_Info[(i)].i_sl_attribute.a_pslValue[(j)].pcStrVal #define res_attr_int(i,j) / r_pls_Info[(i)].i_sl_attribute.a_pslValue[(j)].intval #define res_attr_bool(i,j) / r_pls_Info[(i)].i_sl_attribute.a_pslValue[(j)].boolval #define res_attr_opaque(i,j) / Guttman [Page 13] Internet Draft An API for Service Location 25 November 1996 r_pls_Info[(i)].i_sl_attribute.a_pslValue[(j)].opaqueval /*----------------------------------------------------------------- * SLP errors, can be received from a DA or SA. */ #define SLP_OK 0 #define SLP_LANG_NOT_SUPPORTED 0x01 #define SLP_PROTOCOL_PARSE_ERR 0x02 #define SLP_INVALID_REGISTRATION 0x03 #define SLP_SCOPE_NOT_SUPPORTED 0x04 #define SLP_CHARSET_NOT_UNDERSTOOD 0x05 #define SLP_AUTHENTICATION_INVALID 0x06 /*----------------------------------------------------------------- * Interface errors. */ #define SLP_NOT_SUPPORTED_YET 0x10 #define SLP_REQUEST_TIMED_OUT 0x11 #define SLP_COULD_NOT_INIT_NET_RESOURCES 0x12 #define SLP_COULD_NOT_ALLOCATE_MEMORY 0x13 #define SLP_PARAMETER_BAD 0x14 #define SLP_INTERNAL_NET_ERROR 0x15 #define SLP_INTERNAL_SYSTEM_ERROR 0x16 #ifdef __cplusplus extern "C" { #endif /* for C++ use of C interface */ /*------------------------------------------------------------------- * General interfaces for all clients * * The term "EXPORT" is included so as to make the interface portable * to Win32. For Unix environments, etc. EXPORT is defined as nothing. * For Win32, EXPORT is __declspec(dllimport) for the client library * and __declspec(dllexport) for the library implementation. */ /*------------------------------------------------------------------*/ EXPORT SL_SrvHandle SL_Open( SL_SrvHandle hSL_SrvHandle, /* State created by SL_Open */ const char *pcLangPref, /* Set to the ISO 639 code */ int iDialect, /* Set to 0, reserved */ int iMonoling, /* 1 = Monolingual, 0 = not */ int iMaxWait, /* # seconds max, 0 = default */ int iMultiple, /* 0 = return first result, */ /* 1 = return all results */ SL_CharType slchartype, /* Type for characters used. */ int *piErrValue); /* 0 unless an error occurred */ Guttman [Page 14] Internet Draft An API for Service Location 25 November 1996 /*------------------------------------------------------------------*/ EXPORT void SL_Close( SL_SrvHandle *pSL_SrvHandle); /* pSrvState from SL_Open */ /*------------------------------------------------------------------ * SA interfaces */ /*------------------------------------------------------------------*/ EXPORT int SrvRegister( SL_SrvHandle hSL_SrvHandle, /* State created by SL_Open */ const char *pcURL, /* Unique URL (of reg.) */ const char *pcLang, /* Language code of reg. */ int iDialect, /* Set to 0, reserved. */ SL_CharType slchartype, /* Character type of reg. */ const char *pcAttributes, /* Service Attribute list */ int iLifetime, /* 1..65535 = # of seconds */ /* -1 = CONTINUAL registra- */ /* tion of service */ int iRefreshHint); /* # seconds till refresh */ /*------------------------------------------------------------------*/ EXPORT int SrvDeRegister( SL_SrvHandle hSL_SrvHandle, /* State created by SL_Open */ const char *pcURL, /* URL (of service todereg.) */ const char *pcLang, /* Language code of dereg. */ int iDialect, /* Set to 0, reserved. */ SL_CharType slchartype, /* Character type of dereg. */ const char *pcAttrTags); /* Tags of attrs to dereg. */ /*------------------------------------------------------------------ * UA interfaces */ /*------------------------------------------------------------------*/ EXPORT Result * SL_GetScopes( SL_SrvHandle hSL_SrvHandle); /* State created by SL_Open */ /*------------------------------------------------------------------*/ EXPORT Result * SL_GetSrvTypes( SL_SrvHandle hSL_SrvHandle, /* State created by SL_Open */ const char *pcNamingAuth, /* NULL = default */ const char *pcScope); /* NULL = none */ /*------------------------------------------------------------------*/ EXPORT Result * SL_GetAttrs( SL_SrvHandle hSL_SrvHandle, /* State created by SL_Open */ const char *pcURL, /* Either full or partial */ const char *pcScope, /* Scope of attrs to get */ const char *pcAttrTags); /* Tags for 'selected' attrs */ Guttman [Page 15] Internet Draft An API for Service Location 25 November 1996 /*------------------------------------------------------------------*/ EXPORT Result * SL_GetService( SL_SrvHandle hSL_SrvHandle, /* State created by SL_Open */ const char *pcRequest); /* Request string to supply */ /*------------------------------------------------------------------*/ EXPORT void SrvFreeResult( SL_SrvHandle hSL_SrvHandle, /* State created by SL_Open */ SL_Result **ppResult); /* SL_Result to be freed */ #ifdef __cplusplus } #endif /* for C++ use of C interface */ #endif /* End of the SLP API definition */ /*------------------------------------------------------------------*/ 6.1.2. Interface clarification The values #defined with SLP_ as their prefixes are the return values of the interfaces. In the case of SL_Open, the return value is set via an integer parameter supplied by the caller. In SL_Register and SL_DeRegister the int is returned directly. In the case of all the queries beginning with "SL_Get", the result code is in the Result value returned, in the r_iErrorCode field of the structure. In the case of an error, results MAY be returned on a best effort basis. SL_Open Pass NULL in as the SrvHandle parameter to create a new SrvHandle. Pass an existing SrvHandle parameter to modify the default values associated with it. SL_Register The pcLang and slchartype parameter must be set. See [SLP] for a table of legitimate values for pcLang. iDialect SHOULD be set to 0. See Section 6.3.2. for the syntax of pcAttributes. SL_DeRegister The pcURL paramter must be set. Instead of deregistering the service, one can deregister attributes. In this case the pcLang and slchartype parameter must be set. iDialect SHOULD be set to 0. See Section 6.3.3. for the syntax of pcAttrTags. SL_GetSrvTypes The parameters may be NULL. SL_GetAttrs Guttman [Page 16] Internet Draft An API for Service Location 25 November 1996 The pcURL parameter must be supplied. It can either be a complete service: URL or merely a Service Type string. The semantics of the call vary in this case. The psScope parameter may be NULL. The pcAttrTags parameter may be NULL. If it is not, it follows the grammar in Section 6.3.4. SL_GetService The pcQuery must be supplied. It follows the grammar in Section 6.3.1. 6.1.3. Examples Suppose web servers register themselves with Service Location. The attributes they register are their Scope as well as an index of all the 'home pages' available on the server. The homepages are listed as "::" "::" <description> The web server could do the following: int err = SLP_OK; SrvHandle sh = SL_Open( NULL, /* NULL indicates: Create the SrvHandle */ "en", 0, /* Select English as default language */ 1, /* Monolingual results for replies */ 10, /* 10 seconds max blocking on calls */ 1, /* Return all results */ CHAR_UTF8, /* All requests and replies in UTF8 */ &err); /* error value will be returned in err. */ if (err != SLP_OK) ; /* do something better here */ err = SL_Register( sh, /* supply the SrvHandle */ "service:http://myhost.sun.com", /* supply the URL */ "en", 0, /* reg in English */ CHAR_ASCII, /* reg in UTF8 */ "(SCOPE=ENGINEERING)," /* declare attributes */ "(HOME PAGES=" "schedule/index.html::Schedule::" "This site contains updated timelines for all the work in" "the F.L.O.R.B. project," "snort/releases.html::Bob Snort's Home::" "Release engineer Bob posts results of all the builds here," "specs/index.html::Specs galore::" "Technical specifications for the F.L.O.R.B. and X872" "projects.)", -1, /* continual registration */ Guttman [Page 17] Internet Draft An API for Service Location 25 November 1996 0); /* use default refresh */ if (err != SLP_OK) ; // do something better here A web browser could use Service Location to find a particular web site this way. Unlike web indexing search engines, SLP will keep information up to date and it will be available within a few seconds after a web server registers itself. /* * The client calls SL_Open, exactly as above. */ char *pcPageDescr = NULL; Result *pr = SL_GetAttrs( sh, /* The SrvHandle from SL_Open */ "http", /* The service type desired */ "ENGINEERING", /* The request's scope */ "HOME PAGES"); /* The attribute to return. */ if (pr->r_iErrorCode != SLP_OK) ; // do something better here /* * The client will examine the AttrResult and choose a HOME PAGE */ SL_Free(&pr); /* free previous result */ pr = SL_GetService(sh, "http/engineering/HOME PAGE =" "specs/index.html::Specs galore::" "Technical specifications for the F.L.O.R.B. and X872" "projects./"); This will return a SL_Service with the URL: "service:http://myhost.sun.com" The application can append on the "specs/index.html" from the attribute to obtain a URL for the browser to use: "http://myhost.sun.com/specs/index.html" 6.2. SLP API Java bindings The ServiceLocator is created using a 'singleton' interface. This allows the implementation to keep track of state pertains to all instances of the class. The AttributeResult provides the same information as the C interface, though in a different form. The ServiceResult allows the creation of a Socket for immediate use of the application protocol. 6.2.1. Class definitions public class AttributeResult { public static final int TYPE_STRING = 1; Guttman [Page 18] Internet Draft An API for Service Location 25 November 1996 public static final int TYPE_INT = 2; public static final int TYPE_OPAQUE = 3; public static final int TYPE_BOOL = 4; public int getType(); public int getCharSet(); public String getLanguage(); public int getDialect(); public Vector vAttributes; // may have String, int, boolean or byte[] }; public class ServiceResult { public String sURL; public int iLifetime; public InetAddress iaServiceAddress; public int iPort; }; public class ServiceLocator { // No Constructor // Constants public static final int CHAR_ASCII = 3; public static final int CHAR_LATIN1 = 4; public static final int CHAR_UTF8 = 6; // Class Methods public static ServiceLocator getServiceLocator(); // Instance Methods public String getLanguage(); // default to "en" (English) public int getsDialect(); // default to 0 public boolean getMonolingual(); // default to true public int getMaxWait(); // default to 10 (seconds) public boolean getMultiple(); // default to true public void setLanguage(String sLanguage); public void setDialect(int iDialect); public void setMonolingual(boolean bMonolingual); public void setMaxWait(int iMaxWait); public void setMultiple(boolean iGetMultipleResults); public synchronized void SL_Register( String sURL, String sLanguage, int iDialect, int iCharType, String sAttributes[], int iLifetime, int iRefreshHint) Guttman [Page 19] Internet Draft An API for Service Location 25 November 1996 throws SLPException; public synchronized void SL_DeRegister( String sURL, String sLanguage, int iDialect, int iCharType, String sAttributes) throws SLPException; public synchronized String[] SL_GetScopes(); public synchronized String[] SL_GetServiceTypes( String sNamingAuthority, String sScope) throws SLPException; public synchronized SL_ServiceResult SL_GetService( String sQuery) throws SLPException; public synchronized AttributeResult SL_GetAttrs( String sURL, String sScope, String sAttributeTags) throws SLPException; public synchronized AttributeResult SL_GetAttrs( String sServiceType, String sScope, String sAttributeTags) throws SLPException; }; public class SLPException extends Exception { public SLPException(); public SLPException(String s); }; // Exceptions caused by error conditions detected due to // interaction with remote SLP entities (SAs and DAs) public class SLPLanguageNotSupportedException extends SLPException { public SLPLanguageNotSupportedException(); public SLPLanguageNotSupportedException(String s); }; // Note: This error should never occur. It indicates a flawed // underlying SLP implementation. Hence, it is an error // not an exception. public class SLPParseError extends Error { Guttman [Page 20] Internet Draft An API for Service Location 25 November 1996 public SLPParseException(); public SLPParseException(String s); }; public class SLPInvalidRegistrationException extends SLPExcpetion { public SLPInvalidRegistrationException(); public SLPInvalidRegistrationException(String s); }; public class SLPScopeNotSupportedException extends SLPException { public SLPScopeNotSupportedException(); public SLPScopeNotSupportedException(String s); }; public class SLPCharsetNotUnderstoodException { public SLPCharsetNotUnderstoodException(); public SLPCharsetNotUnderstoodException(String s); }; public class SLPAuthenticationException { public SLPAuthenticationException(); public SLPAuthenticationException(String s); }; // Exceptions caused by error conditions arising through // the program's use of the API or failure of the SLP // implementation. public class SLPNotSupportedYet extends SLPException { public SLPNotSupportedYet(); public SLPNotSupportedYet(String s); }; public class SLPTimeOutException extends SLPException { public SLPTimeOutException(); public SLPTimeOutException(String s); }; public class SLPInitNetException extends SLPException { public SLPInitNetException(); public SLPInitNetException(String s); }; // The 'message' SHOULD indicate which parameter was bad. public class SLPParameterBadException extends SLPException { public SLPParameterBadException(); public SLPParameterBadException(String s); }; public class SLPInternalNetError extends SLPException { public SLPInternalNetError(); Guttman [Page 21] Internet Draft An API for Service Location 25 November 1996 public SLPInternalNetError(String s); }; public class SLPInternalSystemError extends SLPException { public SLPInternalSystemError(); public SLPInternalSystemError(String s); }; 6.2.2. Examples A simplest application is: A server of type blah makes a service advertisement: ServiceLocator sl = ServiceLocator.getServiceLocator(); sl.SL_Register("service:blah://myhost.sun.com", // service URL. "en", 0, // Attributes is in English. "(SCOPE=ADMIN)", // The attribute. CHAR_ASCII, // Attribute uses ASCII. -1); // Continual registration. A blah client system can discover this with the following: try { ServiceLocator sl = ServiceLocator.getServiceLocator(); ServiceResult sr = sl.SL_GetService("blah/admin//"); catch (SLPException) ; // do something better here try Socket s = new Socket(sr.iaServiceAddress, sr.iPort); catch (IOException) ; // do something better here // ... now use s to do blah client-server stuff ... Note that the scope matching is case insensitive. The query string is omitted, so the request will return all blah services. The client may then proceed to use the blah service, simply by creating a socket from the information in the ServiceResult. 6.3. Syntax for string parameters The definitions which follow are cumulative. The syntax is specified using Augmented BNF [ABNF]. There are some rules which specify explicitely what characters are NOT permitted. For the syntax of the service: URL, see [SRV]. 6.3.1. Query Syntax This is used in SL_GetService (See Section 3.7.) A Query may take two forms. white = SPACE / TAB / CR / LF Guttman [Page 22] Internet Draft An API for Service Location 25 November 1996 query = listquery / ; conjunction query generalquery / ; complex query *white ; ie. the query matches everything These are defined in the next sections. The list-query is a very simple form. The general-query allows arbitrarily complex logical combinations of conditions. Common syntax to both kinds of queries follows: predicate = srvtype [ "." na ] "/" scope "/" query "/" schemechar = ALPHA / "+" / "-" srvtype = schemechar na = schemechar ; omit na when it is "IANA", the default scope = ; Any string with the following restrictions: ; "/", ",", and ":" are not allowed in this ; string. "LOCAL" and "REMOTE" scope strings are ; reserved. safe-char = ; Any character with the following restrictions: ; "(", ")", ",", "=", "!", ">", "<", "/", "*" ; are not allowed. attr-tag = 1*safe-char safer-char = ; As safe-char but SPACE is also not allowed. keyword = 1*safer-char query-item = keyword / attr-tag comp-op value comp-op = "!=" / "==" / "<" / "<=" / ">" / ">=" value = string / integer / boolean / opaque string = 1*safe-char integer = [-] 1*DIGIT ; The integer MUST fall within the range of ; values a 32 bit integer may take, ie. ; "-2147483648" to "2147483647". boolean = "TRUE" / "FALSE" ; These values are the only exception to the ; Internationalization rules in Section 8.0. ; Independent of the translation of the ; attributes, the boolean values remain the ; indicated strings. rad64-char = ALPHA / DIGIT / "+" / "-" / white-sp Guttman [Page 23] Internet Draft An API for Service Location 25 November 1996 opaque = 1*DIGIT ":" 4*rad64-char ; The digits define the original length of the ; opaque value. The restricted character string ; is the radix-64 encoding of the opaque value. ; See [RFC 1521], Section 5.2. ; NOTE: White space is ignored in decoding ; radix-64 values. Note on the use of white space: A string is considered to be a token in the case of a tag or <string> value. In this case, the string is 'trimmed'. White space interior to a string token is left alone, while white space between the tokens is removed. For example: " some name = some value , another example " would be trimmed to "some name" "=" "some value" and "another example". Note on string matching: Attribute tags and values may be used by some protocols for directory look-up. In this case, the following rules should be applied for string matching of attribute strings. String matching MUST be done after character escape encoding has been removed, white space has been trimmed. In addition, string matching SHOULD be case insensitive. 6.3.1.1. List Query Syntax list-query = 1#query-item 6.3.1.2. General Query Syntax general-query = "(" "&" general-query query-item-list ")" / "(" "|" general-query query-item-list ")" / "(" query-item ")" query-item-list = general-query / general-query query-item-list 6.3.2. Attribute Registration List This is used in SL_Register (See Section 3.3.) attr-reg-list = 1#attr-reg Guttman [Page 24] Internet Draft An API for Service Location 25 November 1996 attr-reg = keyword / "(" attr-tag = 1#value ") 6.3.3. Attribute Deregistration List This is used in SL_DeRegister (See Section 3.4.) attr-dereg-list = 1#attr-dereg attr-dereg = keyword / attr-tag 6.3.4. Attribute Selection List Syntax This is used in SL_GetAttrs (See Section 3.8.) attr_select_list = 1#attr-select attr_select = keyword / attr-tag / partial-tag partial_tag = 1*safe-char "*" 6.4. Interpretation of SLP error values The following errors occur as a result of interaction between SLP entities: SLP_LANG_NOT_SUPPORTED A request was made in a language not supported by a DA. If the request could be handled by the DA in a language other than the requested one, it will do so. The UA may explicitely declare itself to be monolingual, in which case the absense of service advertisement information in the requested language will elicit this error. SLP_PROTOCOL_PARSE_ERR The internal implementation of SLP created a SLP message which was rejected by a remote SLP entity. SLP_INVALID_REGISTRATION The service advertisement created with SL_Register was rejected by a DA. This is due to a malformed URL or attributes. SLP_SCOPE_NOT_SUPPORTED A DA will return this error code if a UA or SA sends a request or registration lacking its configured scope. Note that DAs without a Scope never issue this error. SLP_CHARSET_NOT_UNDERSTOOD DAs and SAs have string storage, comparison, copying and other capabilities in only a narrow range of character sets. Thus Guttman [Page 25] Internet Draft An API for Service Location 25 November 1996 requests or registrations in unsupported character sets will illicit this error. SLP messages using US-ASCII will always be supported. SLP_AUTHENTICATION_INVALID If the SLP framework supports authentication, this error will arise when a remote DA fails to accept a registration. This error will not occur if a UA rejects a reply to a request: The UA will simply silently discard (and possibly log) the rejected reply. The following errors are generated through a program interacting with the API and SLP implementation. They also indicated internal failures which are not fatal. SLP_NOT_SUPPORTED_YET When a particular feature is used which is not implemented in the API, this error is returned. This error SHOULD not occur. SLP_REQUEST_TIMED_OUT When no reply can be obtained in the time specified by the configured timeout interval, this error is returned instead. SLP_COULD_NOT_INIT_NET_RESOURCES If the SLP framework cannot initialize properly, this error will be returned. SLP_COULD_NOT_ALLOCATE_MEMORY If the API or SLP implementation fails to allocate memory, the operation is aborted and returns this. SLP_PARAMETER_BAD If a parameter passed into an interface is bad, this error is returned. SLP_INTERNAL_NET_ERROR The failure of networking during normal operations causes this error to be returned. SLP_INTERNAL_SYSTEM_ERROR A basic failure of the SLP implementation causes this error to be returned. This occurs when a system call or library fails. The operation could not recover. 7. Security Considerations Guttman [Page 26] Internet Draft An API for Service Location 25 November 1996 SLP will make use of an existing host based authentication framework once it becomes available as an Internet Standard. [RFC1825] In the absense of this, it is extremely easy for anyone to register any service with Service Location. SLP does not authenticate the source of service advertisements, either at the DA or when the UA receives it. For this reason, use of SLP on open networks, such as the internet, should be avoided. A DA may be provided on an open network with registration capabilities disabled; but this is of limited utility since a UA would not be able to distinguish it from a DA full of impersonations. For this reason, SLP should only be used in 'private' networks, as those behind firewalls where users are expected to perform in a responsible manner. SLP is neutral to the protocols clients and servers use between themselves. Strong bidirectional authentication at higher levels (ie. transport level: "The SSL Protocol, Version 3" [SSH] or application level: "Generic Security Service Application Program Interface" [GSSAPI],) would obviate the risk of masquerading by an adversary using SLP. An adversary could delete valid service advertisements and deny UAs knowledge of existing services. 8. Internationalization Considerations The service: URL itself must be encoded using the rules set forth in [RFC1738]. The character set encoding is limited to specific ranges within the US-ASCII character set [ASCII]. The attribute information associated with the service: URL may be expressed in any character set, and in any language. 8.1. Character Set identification and use The way of identifying the character set used is the IANA Character Set registry MIB Enum value. [CHAR-REG] It can be assumed that US-ASCII [ASCII] will be supported. Programs which register or request information using other character sets must be prepared for the possibility that the SLP framework is not capable of supporting it. In this case, they should fall back to US-ASCII if possible. 8.2. Language identification and translation The language used in attribute string should be identified using a Guttman [Page 27] Internet Draft An API for Service Location 25 November 1996 Language tag as defined by [ISO-639]. A program registering a service should use the strings provided in the Service Type template which defines the range of standard values. If this document provides translations to other languages, the service advertisement should be made in each. If however no translation exists, or there is no standardized Service Type template, translation may still be provided on a "best effort" basis. A service advertisement is made in multiple languages, one after the other. The same information is registered using SL_Register, though the Language tag differs and the strings are translated. Many attribute strings are 'literal' and will not be translated. See [SRV] for details. 9. Bibliography [ABNF] D. Crocker, "Augmented BNF for Syntax Specifications: ABNF", Work in progress, November 1996. [ASCII] "Coded Character Set -- 7-bit American Standard code for Information Interchange", ANSI X3.4-1986. [CHAR-REG] IANA Character Set registry, <URL:http://www.isi.edu /in-notes/iana/assignments/character-sets>. [GSSAPI] J. Linn, "Generic Security Service Application Program Interface", RFC 1508, September 1993. Also: J. Linn, "Generic Security Service Application Program Interface, Version 2", A work in progress, November 1996. [RFC1825] R. Atkinson, "Security Architecture for the Internet Protocol", RFC 1825, July 1995. [SSH] A. Freier, P. Karlton, P. Kocher, "The SSL Protocol, Version 3.0", A work in progress, November 1996. [SLP] J. Veizades, E. Guttman, C. Perkins & S. Kaplan, Service Location Protocol", Work in progress, November 1996. [SRV] E. Guttman, "The service: URL Scheme", Work in progress, November 1996. [ISO-639] This standard is provided as Appendix A of [SLP]. 10. Author's Address Guttman [Page 28] Internet Draft An API for Service Location 25 November 1996 Erik Guttman Sun Microsystems, Inc. Gaisbergstr. 6 D-69115 Heidelberg Germany Phone: +1 415 336 6697 email: Erik.Guttman@eng.sun.com This memo expires on May 25, 1997 Guttman [Page 29]