Home | History | Annotate | Download | only in client_channel
      1 /*
      2  *
      3  * Copyright 2017 gRPC authors.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  */
     18 
     19 #include <grpc/support/port_platform.h>
     20 
     21 #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
     22 
     23 #include <string.h>
     24 
     25 #include <grpc/support/alloc.h>
     26 
     27 //
     28 // grpc_proxy_mapper_list
     29 //
     30 
     31 typedef struct {
     32   grpc_proxy_mapper** list;
     33   size_t num_mappers;
     34 } grpc_proxy_mapper_list;
     35 
     36 static void grpc_proxy_mapper_list_register(grpc_proxy_mapper_list* list,
     37                                             bool at_start,
     38                                             grpc_proxy_mapper* mapper) {
     39   list->list = static_cast<grpc_proxy_mapper**>(gpr_realloc(
     40       list->list, (list->num_mappers + 1) * sizeof(grpc_proxy_mapper*)));
     41   if (at_start) {
     42     memmove(list->list + 1, list->list,
     43             sizeof(grpc_proxy_mapper*) * list->num_mappers);
     44     list->list[0] = mapper;
     45   } else {
     46     list->list[list->num_mappers] = mapper;
     47   }
     48   ++list->num_mappers;
     49 }
     50 
     51 static bool grpc_proxy_mapper_list_map_name(grpc_proxy_mapper_list* list,
     52                                             const char* server_uri,
     53                                             const grpc_channel_args* args,
     54                                             char** name_to_resolve,
     55                                             grpc_channel_args** new_args) {
     56   for (size_t i = 0; i < list->num_mappers; ++i) {
     57     if (grpc_proxy_mapper_map_name(list->list[i], server_uri, args,
     58                                    name_to_resolve, new_args)) {
     59       return true;
     60     }
     61   }
     62   return false;
     63 }
     64 
     65 static bool grpc_proxy_mapper_list_map_address(
     66     grpc_proxy_mapper_list* list, const grpc_resolved_address* address,
     67     const grpc_channel_args* args, grpc_resolved_address** new_address,
     68     grpc_channel_args** new_args) {
     69   for (size_t i = 0; i < list->num_mappers; ++i) {
     70     if (grpc_proxy_mapper_map_address(list->list[i], address, args, new_address,
     71                                       new_args)) {
     72       return true;
     73     }
     74   }
     75   return false;
     76 }
     77 
     78 static void grpc_proxy_mapper_list_destroy(grpc_proxy_mapper_list* list) {
     79   for (size_t i = 0; i < list->num_mappers; ++i) {
     80     grpc_proxy_mapper_destroy(list->list[i]);
     81   }
     82   gpr_free(list->list);
     83   // Clean up in case we re-initialze later.
     84   // TODO(ctiller): This should ideally live in
     85   // grpc_proxy_mapper_registry_init().  However, if we did this there,
     86   // then we would do it AFTER we start registering proxy mappers from
     87   // third-party plugins, so they'd never show up (and would leak memory).
     88   // We probably need some sort of dependency system for plugins to fix
     89   // this.
     90   memset(list, 0, sizeof(*list));
     91 }
     92 
     93 //
     94 // plugin
     95 //
     96 
     97 static grpc_proxy_mapper_list g_proxy_mapper_list;
     98 
     99 void grpc_proxy_mapper_registry_init() {}
    100 
    101 void grpc_proxy_mapper_registry_shutdown() {
    102   grpc_proxy_mapper_list_destroy(&g_proxy_mapper_list);
    103 }
    104 
    105 void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper) {
    106   grpc_proxy_mapper_list_register(&g_proxy_mapper_list, at_start, mapper);
    107 }
    108 
    109 bool grpc_proxy_mappers_map_name(const char* server_uri,
    110                                  const grpc_channel_args* args,
    111                                  char** name_to_resolve,
    112                                  grpc_channel_args** new_args) {
    113   return grpc_proxy_mapper_list_map_name(&g_proxy_mapper_list, server_uri, args,
    114                                          name_to_resolve, new_args);
    115 }
    116 bool grpc_proxy_mappers_map_address(const grpc_resolved_address* address,
    117                                     const grpc_channel_args* args,
    118                                     grpc_resolved_address** new_address,
    119                                     grpc_channel_args** new_args) {
    120   return grpc_proxy_mapper_list_map_address(&g_proxy_mapper_list, address, args,
    121                                             new_address, new_args);
    122 }
    123