1 //
2 // Copyright 2019 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <grpc/support/port_platform.h>
18
19 #include "src/core/load_balancing/grpclb/grpclb_balancer_addresses.h"
20
21 #include <stddef.h>
22
23 #include <utility>
24
25 #include "src/core/lib/channel/channel_args.h"
26 #include "src/core/lib/gpr/useful.h"
27
28 // Channel arg key for the list of balancer addresses.
29 #define GRPC_ARG_GRPCLB_BALANCER_ADDRESSES \
30 GRPC_ARG_NO_SUBCHANNEL_PREFIX "grpc.grpclb_balancer_addresses"
31
32 namespace grpc_core {
33
34 namespace {
35
BalancerAddressesArgCopy(void * p)36 void* BalancerAddressesArgCopy(void* p) {
37 EndpointAddressesList* endpoint_list = static_cast<EndpointAddressesList*>(p);
38 return new EndpointAddressesList(*endpoint_list);
39 }
40
BalancerAddressesArgDestroy(void * p)41 void BalancerAddressesArgDestroy(void* p) {
42 EndpointAddressesList* endpoint_list = static_cast<EndpointAddressesList*>(p);
43 delete endpoint_list;
44 }
45
BalancerAddressesArgCmp(void * p,void * q)46 int BalancerAddressesArgCmp(void* p, void* q) {
47 auto* endpoint_list1 = static_cast<EndpointAddressesList*>(p);
48 auto* endpoint_list2 = static_cast<EndpointAddressesList*>(q);
49 if (endpoint_list1 == nullptr || endpoint_list2 == nullptr) {
50 return QsortCompare(endpoint_list1, endpoint_list2);
51 }
52 if (endpoint_list1->size() > endpoint_list2->size()) return 1;
53 if (endpoint_list1->size() < endpoint_list2->size()) return -1;
54 for (size_t i = 0; i < endpoint_list1->size(); ++i) {
55 int retval = (*endpoint_list1)[i].Cmp((*endpoint_list2)[i]);
56 if (retval != 0) return retval;
57 }
58 return 0;
59 }
60
61 const grpc_arg_pointer_vtable kBalancerAddressesArgVtable = {
62 BalancerAddressesArgCopy, BalancerAddressesArgDestroy,
63 BalancerAddressesArgCmp};
64
65 } // namespace
66
CreateGrpclbBalancerAddressesArg(const EndpointAddressesList * endpoint_list)67 grpc_arg CreateGrpclbBalancerAddressesArg(
68 const EndpointAddressesList* endpoint_list) {
69 return grpc_channel_arg_pointer_create(
70 const_cast<char*>(GRPC_ARG_GRPCLB_BALANCER_ADDRESSES),
71 const_cast<EndpointAddressesList*>(endpoint_list),
72 &kBalancerAddressesArgVtable);
73 }
74
FindGrpclbBalancerAddressesInChannelArgs(const ChannelArgs & args)75 const EndpointAddressesList* FindGrpclbBalancerAddressesInChannelArgs(
76 const ChannelArgs& args) {
77 return args.GetPointer<const EndpointAddressesList>(
78 GRPC_ARG_GRPCLB_BALANCER_ADDRESSES);
79 }
80
SetGrpcLbBalancerAddresses(const ChannelArgs & args,EndpointAddressesList endpoint_list)81 ChannelArgs SetGrpcLbBalancerAddresses(const ChannelArgs& args,
82 EndpointAddressesList endpoint_list) {
83 return args.Set(
84 GRPC_ARG_GRPCLB_BALANCER_ADDRESSES,
85 ChannelArgs::Pointer(new EndpointAddressesList(std::move(endpoint_list)),
86 &kBalancerAddressesArgVtable));
87 }
88
89 } // namespace grpc_core
90