Export (0) Print
Expand All

4.1.16.3 Server Behavior of the IDL_DRSQuerySitesByCost Method

Informative summary of behavior: Given a sitefromSite and an array of sites toSites, the server returns an array that contains the cost from fromSite to each element of toSite, where the cost is defined as follows.

The server computes a weighted graph G = (V, A). Each vertex in V corresponds to a siteobject. Each arc in A corresponds to a siteLink object that connects two vertices in V; the weight of an arc is the value of attributecost on the arc's siteLink object. The cost of a path in the graph is the sum of the arc weights on the path. The cost from one site to another is the minimum-cost path between the two sites.

The model just described corresponds to fully transitive communications between sites: If site a communicates with site b and site b communicates with site c, then site a communicates with site c by routing through b. Replication can be configured to restrict transitive communication to sites specified in the same siteLinkBridge object. Suppose there is a siteLink object for site a and site b, and a siteLink object for site b and site c, but no siteLink object for site a and site c. If both of the siteLink objects are specified on the same siteLinkBridge object, site a can communicate with site c by routing through b. If no such siteLinkBridge object exists, site a cannot communicate with site c.

To calculate the cost when siteLinkBridge objects are used, let nBridges be the number of siteLinkBridge objects. For each k in the subrange [0 .. nBridges-1], construct a weighted graph G[k] = (V, A[k]) using siteLinkBridge object b[k]. Graph G[k] has the same vertex set as G, but its arc set A[k] is a subset of A, including only the arcs listed in attribute siteLinkList on siteLinkBridge object b[k]. Then the cost from site a to site c is the minimum of the following costs:

  1. The cost of the arc, if any, from a to c in G.

  2. For each k in the subrange [0 .. nBridges-1], the cost of the minimum cost path, if any, from a to c in G[k].

Any authenticated user can perform this operation; no access checking is performed.<35>

ULONG
IDL_DRSQuerySitesByCost(
    [in, ref] DRS_HANDLE hDrs,
    [in] DWORD dwInVersion,
    [in, ref, switch_is(dwInVersion)]
        DRS_MSG_QUERYSITESREQ *pmsgIn,
    [out, ref] DWORD *pdwOutVersion,
    [out, ref, switch_is(*pdwOutVersion)]
        DRS_MSG_QUERYSITESREPLY *pmsgOut)

msgIn: DRS_MSG_QUERYSITESREQ_V1
vSet, slSet, sbSet : set of DSName
aSet, aSetB, aSetC, aSetD: WeightedArcSet
siteContainer, ipObject, fromSite, toSite: DSName
u, v, sl, sb: DSName
i, c: integer
min: WeightedArc
ul : ULONG

ValidateDRSInput(hDrs, 24)

pdwOutVersion^ := 1
pmsgOut^.V1.cToSites := 0
pmsgOut^.V1. rgCostInfo := null
pmsgOut^.V1.dwFlags := 0

/* Perform input validation,
 * initialize siteContainer, ipObject, fromSite. */
if dwInVersion ≠ 1 then
  return ERROR_DS_DRA_INVALID_PARAMETER
endif
msgIn := pmsgIn^.V1
ul := ValidateSiteRDN(msgIn.pwszFromSite)
if 0 ≠ ul then
  return ul
endif
if msgIn.cToSites > 0 and msgIn.rgszToSites = null then
  return ERROR_INVALID_PARAMETER
endif
for i := 0 to msgIn.cToSites – 1
   ul := ValidateSiteRDN(msgIn.rgszToSites[i])
   if 0 ≠ ul then
     return ul
   endif
endfor
siteContainer := DescendantObject(ConfigNC(), "CN=Sites,")
ipObject := DescendantObject(ConfigNC(),
    "CN=IP,CN=Inter-Site Transports,CN=Sites,")
fromSite := select one v from children siteContainer where
    site in v!objectClass and v!name = msgIn.pwszFromSite
if fromSite = null then
  return ERROR_DS_OBJ_NOT_FOUND
endif

/* Construct the vertex set vSet. */
vSet := select all v from children siteContainer where
    site in v!objectClass
if vSet = {} then
  return ERROR_DS_OBJ_NOT_FOUND
endif

/* Construct the arc set aSet. */
slSet := select all v from children ipObject where
    siteLink in v!objectClass
foreach sl in slSet
  foreach u in sl!siteList
    foreach v in sl!siteList - {u}
      aSet := aSet + {[initial: u, final: v, cost: sl!cost]}
    endfor
  endfor
endfor

/* Construct minimum-cost arc set aSetC. 
 * See [MS-ADTS] section 6.1.1.2.2.3.1, "IP Transport Container", for
 * the definition of the NTDSTRANSPORT_OPT_BRIDGES_REQUIRED option. */
if NTDSTRANSPORT_OPT_BRIDGES_REQUIRED in ipObject!options then
  /* Perform construction using siteLinkBridge objects.
   * Initial minimum cost is the cost of a direct arc if any. */
  aSetC := aSet
  sbSet := select all v from children ipObject where
      siteLinkBridge in v!objectclass
  foreach sb in sbSet
    /* Compute the minimum cost using this siteLinkBridge. */
    aSetB := {}
    foreach sl in sb!siteLinkList
      foreach u in sl!siteList
        foreach v in sl!siteList - {u}
          aSetB := aSetB + {[initial: u, final: v, cost: sl!cost)}
        endfor
      endfor
    endfor
    aSetD := MinWeightPath(vSet, aSetB)
    /* Here aSetD contains the minimum cost arc set using this
     * siteLinkBridge. Improve the current minimum cost using 
     * aSetD. */
    foreach [initial: u, final: v, cost: c] in aSetD
      min := select one t from aSetC where 
          t.initial = u and t.final = v
      if min = null then
        aSetC := aSetC + {[initial: u, final: v, cost: c)}
      else if min.cost > c then
        aSetC := aSetC - {[initial: u, final: v, cost: min.cost]}
                       + {[initial: u, final: v, cost: c)}
      endif
    endfor
  endfor
else
  /* Fully transitive network, ignore siteLinkBridge objects. */
  aSetC := MinWeightPath(vSet, aSet)
endif

/* Construct result message. */
pdwOutVersion^ := 1
pmsgOut^.V1.cToSites := msgIn.cToSites
pmsgOut^.V1.dwFlags := 0
for i:= 0 to msgIn.cToSites - 1
  toSite := select one v from children siteContainer where 
      site in v!objectClass and v!name = msgIn.rgszToSites[i]
  if not (toSite in vSet) then
    pmsgOut^.V1.rgCostInfo[i].dwErrorCode := ERROR_DS_OBJ_NOT_FOUND
    pmsgOut^.V1.rgCostInfo[i].dwCost := 0xffffffff
  else 
    min := select one t from aSetC where
        t.initial = fromSite and t.final = toSite
    if min ≠ null then 
      pmsgOut^.V1.rgCostInfo[i].dwErrorCode := 0
      pmsgOut^.V1.rgCostInfo[i].dwCost := min.cost
    else
      pmsgOut^.V1.rgCostInfo[i].dwErrorCode = 0
      pmsgOut^.V1.rgCostInfo[i].dwCost := 0xffffffff
    endif
  endif
endfor

return 0
 
Show:
© 2014 Microsoft