2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License, Version 1.0 only 2N/A * (the "License"). You may not use this file except in compliance 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A * All UA functions use target lists to select and manage their 2N/A * network targets. There are two types of network targets: unicast (uc) 2N/A * and multicast (mc) -- multicast will also work for broadcast. This 2N/A * module organizes unicast targets into an efficient ordering. The 2N/A * targeting structure can be though of as a 2-dimensional matrix, with 2N/A * the following axes: 2N/A * unicast failovers ---> 2N/A * Callers walk down the unicast targets, unicasting to each. If any 2N/A * unicast target fails, callers then walk to the right, through failover 2N/A * targets until they either find one that works, or there are no more 2N/A * The targeting heuristic orders the unicast targets so that those 2N/A * DAs which support the greatest number of requested scopes are called 2N/A * first, thus minimizing the number of unicasts which need to be done. 2N/A * Within groups of DAs supporting the same scope coverage, the DAs are 2N/A * sorted according to network proximity relative to the local host: 2N/A * DAs on the local host come first, then those on a same subnet, then 2N/A * all other (remote) DAs. 2N/A * A given DA is called no more than once, and failed DAs are skipped 2N/A * after they have been marked 'failed'. 2N/A * All access to a target list is done through the following functions 2N/A * There are two opaque types: 2N/A * slp_target_list_t: A handle to a target list 2N/A * slp_target_t: A handle to an individual target. slp_get_target_sin 2N/A * will extract an inet address for this target. 2N/A * There are the following accessor functions: 2N/A * slp_new_target_list: creates a new target list for the given scopes, 2N/A * and populates with all known DAs for these scopes. 2N/A * slp_get_uc_scopes: returns a list of all scopes for which there are 2N/A * DAs (and which can thus be used for unicasts) 2N/A * slp_get_mc_scopes: returns a list of all scopes for which there are 2N/A * no DAs (and which must thus be used for multicasts). 2N/A * slp_next_uc_target: Returns a slp_target_t handle for the next unicast 2N/A * target, or NULL for none. 2N/A * slp_next_failover: Returns the next failover DA for a given target, or 2N/A * slp_get_target_sin: extracts a sockaddr_in for a given slp_target_t; 2N/A * slp_mark_target_used: callers should mark a slp_target_t used after 2N/A * successfully communicating with that target. 2N/A * slp_mark_target_failed: callers should mark a slp_target_t failed after 2N/A * trying and failing to communicate with a target. 2N/A * slp_destroy_target_list: destroys and frees a target list and all its 2N/A * associated resources. 2N/A * slp_fabricate_target: Creates a slp_target_t from a given sockaddr_in. 2N/A * This is useful for situations such as when a 2N/A * multicast routine needs to hand off to a TCP 2N/A * routine (due to overflow), and there is no target 2N/A * list available. Fabricated targets should be free'd 2N/A * with slp_free_target; the input sin will duplicated 2N/A * in the target, so the caller can free it after 2N/A * calling slp_fabricate_target. 2N/A * slp_free_target: Frees an slp_target_t created by slp_fabricate_target. 2N/A * This should not be used to free any other target. 2N/A /* count the number of scopes in the list */ 2N/A /* create a new target list */ 2N/A /* As scopes are added to uc list, they are removed from the mc list */ 2N/A /* all scopes remain multicast scopes; useful for SAAdverts */ 2N/A /* DAs from active and passive discovery */ 2N/A /* Unpack the reply */ 2N/A /* tag call as internal */ 2N/A /* invoke last call */ 2N/A /* revert internal call tag */ 2N/A * tl->DAs now points to a list of DAs sorted by the number of 2N/A * relevant scopes they serve. Using this ordering, populate the 2N/A * scope array lists. 2N/A /* find the next unused target */ 2N/A /* get next failover */ 2N/A /* else nothing more we can do */ 2N/A return (
NULL);
/* already did this scope */ 2N/A /* free da node list */ 2N/A /* free scope target linked lists */ 2N/A /* free scope array */ 2N/A /* free any char * lists in use */ 2N/A /* free the target list struct */ 2N/A * for each scope in tl->uc_scopes: 2N/A * add this DA if it serves the scope. 2N/A /* add this DA node to this scope's target list */ 2N/A /* find the end of the target list */ 2N/A /* find its place in the list */ 2N/A /* found a coverage grouping; now sort by proximity */ 2N/A /* we're at the head */ 2N/A /* didn't find a place in the list, so add it at the end */ 2N/A /* dup url so as not to corrupt da cache */ 2N/A /* parse url into a SLPSrvURL struct */ 2N/A /* determine proximity */ 2N/A * sort the DAs into the entry list, ranked by the number of 2N/A * relevant scopes they serve (coverage). 2N/A /* URL part should be of the form 'scopes=...' */ 2N/A /* cut off host scope at end */ 2N/A /* skip the =[hostname] at the end */ 2N/A /* copy out the scopes part, since url will be freed after this call */ 2N/A /* add to uc list; remove from mc list */ 2N/A * Takes a scopes list of the form 's1,s2,s3,...' and formats it into 2N/A * an LDAP search filter of the form '(|(SCOPETAG=s1)(SCOPETAG=s2)...)'. 2N/A * 'scopes' contains the scopes list; 'q' is a buffer allocated 2N/A * by the caller into which the result will be placed. 2N/A *q++ =
'('; *q++ =
'&';
2N/A *q++ =
'('; *q++ =
'|';