Example #1
0
/*
 * Create a service descriptor from an array of methods.
 */
int NaClSrpcServiceHandlerCtor(NaClSrpcService* service,
                               const NaClSrpcHandlerDesc* handler_desc) {
  char*       service_str;
  nacl_abi_size_t  str_length;
  NaClSrpcMethodDesc* methods = NULL;
  uint32_t method_count = 0;

  /* Initialize the struct, so that failures can be cleaned up properly. */
  service->service_string = NULL;
  service->service_string_length = 0;
  service->rpc_descr = NULL;
  service->rpc_count = 0;
  /* Add the service_discovery method to the table. */
  methods = BuildMethods(handler_desc, &method_count);
  if (NULL == methods) {
    goto cleanup;
  }
  service_str = BuildSDString(methods, method_count, &str_length);
  if (NULL == service_str) {
    goto cleanup;
  }
  service->service_string = service_str;
  service->service_string_length = str_length;
  service->rpc_descr = methods;
  service->rpc_count = method_count;
  return 1;
 cleanup:
  FreeMethods(methods, method_count);
  return 0;
}
/*
 * Destroy a service descriptor.
 */
void NaClSrpcServiceDtor(NaClSrpcService* service) {
  if (NULL == service) {
    return;
  }
  /* Free the method descriptors. */
  FreeMethods((NaClSrpcMethodDesc*) service->rpc_descr, service->rpc_count);
  /* Free the service discovery string. */
  free((char*) service->service_string);
}
Example #3
0
/*
 * The method tables passed to construction do not contain "intrinsic" methods
 * such as service discovery and shutdown.  Build a complete table including
 * those from a given input.
 */
static NaClSrpcMethodDesc* BuildMethods(
    const struct NaClSrpcHandlerDesc* methods,
    uint32_t* method_count) {
  static const char* kSDDescString = "service_discovery::C";
  NaClSrpcMethodDesc* complete_methods = NULL;
  uint32_t i;
  const char* nul_loc;

  /* Compute the number of methods to export. */
  *method_count = 0;
  while (NULL != methods[*method_count].entry_fmt)
    ++*method_count;
  /* Add one extra method for service discovery. */
  ++*method_count;
  /* Allocate the method descriptors. One extra for NULL termination. */
  complete_methods = (NaClSrpcMethodDesc*)
      calloc(*method_count + 1, sizeof(*complete_methods));
  if (NULL == complete_methods) {
    return NULL;
  }
  /* Copy the methods passed in, adding service discovery as element zero. */
  nul_loc = ParseOneEntry(kSDDescString,
                          (char**) &complete_methods[0].name,
                          (char**) &complete_methods[0].input_types,
                          (char**) &complete_methods[0].output_types);
  if (nul_loc == NULL) {
    goto cleanup;
  }
  complete_methods[0].handler = ServiceDiscovery;
  for (i = 0; i < *method_count - 1; ++i) {
    nul_loc = ParseOneEntry(methods[i].entry_fmt,
                            (char**) &complete_methods[i + 1].name,
                            (char**) &complete_methods[i + 1].input_types,
                            (char**) &complete_methods[i + 1].output_types);
    if (nul_loc == NULL) {
      goto cleanup;
    }
    complete_methods[i + 1].handler = methods[i].handler;
  }
  /* Add the NULL terminator */
  complete_methods[*method_count].name = NULL;
  complete_methods[*method_count].input_types = NULL;
  complete_methods[*method_count].output_types = NULL;
  complete_methods[*method_count].handler = NULL;
  /* Return the array */
  return complete_methods;

 cleanup:
  FreeMethods(complete_methods, *method_count);
  return NULL;
}
int NaClSrpcServiceStringCtor(NaClSrpcService* service, const char* str) {
  NaClSrpcMethodDesc* methods = NULL;
  const char* p;
  uint32_t i;
  uint32_t rpc_count;
  size_t rpc_count_size_t;

  /* Count the number of rpc methods */
  rpc_count = 0;
  for (p = str; *p != '\0'; ) {
    char* next_p = strchr(p, '\n');
    if (NULL == next_p) {
      /* malformed input -- no remaining \n character was found */
      goto cleanup;
    }
    p = next_p + 1;
    ++rpc_count;
    if (0 == rpc_count) {
      /* uint32_t overflow detected. */
      goto cleanup;
    }
  }
  /*
   * The front end knows the next comparison is useless due to the range of
   * uint32_t.  And furthermore at least one version of gcc knows that a
   * cast doesn't really change that fact.  Hence, assign to a new variable
   * of size_t type.
   */
  rpc_count_size_t = (size_t) rpc_count;
  /* Allocate and clear the descriptor array */
  if (rpc_count_size_t >= SIZE_T_MAX / sizeof(*methods)) {
    goto cleanup;
  }
  methods = (NaClSrpcMethodDesc*) malloc(rpc_count_size_t * sizeof(*methods));
  if (NULL == methods) {
    goto cleanup;
  }
  memset(methods, 0, rpc_count_size_t * sizeof(*methods));
  /* Parse the list of method descriptions */
  p = str;
  for (i = 0; i < rpc_count; ++i) {
    const char* newline_loc;

    newline_loc = ParseOneEntry(p,
                                (char**) &methods[i].name,
                                (char**) &methods[i].input_types,
                                (char**) &methods[i].output_types);
    if (NULL == newline_loc || '\n' != *newline_loc) {
      goto cleanup;
    }
    p = newline_loc + 1;
    /* The handler is not set from service_discovery strings */
    methods[i].handler = NULL;
  }
  service->service_string = strdup(str);
  service->service_string_length = nacl_abi_size_t_saturate(strlen(str));
  service->rpc_descr = methods;
  service->rpc_count = rpc_count;
  return 1;

 cleanup:
  FreeMethods(methods, rpc_count);
  return 0;
}