Exemplo n.º 1
0
static inline bool do_relative_http_request(struct update_info *info,
		const char *url, const char *file)
{
	long response_code;
	char *full_url = get_path(url, file);
	bool success = do_http_request(info, full_url, &response_code);
	bfree(full_url);
	return success && response_code == 200;
}
static bool
delete_tep_from_packet_reflectors( transaction_entry *entry, uint32_t vni, const char *address ) {
  debug( "Deleting a tunnel endpoint from packet reflectors ( entry = %p, vni = %#x, address = %s ).",
         entry, vni, address != NULL ? address : "" );

  assert( entry != NULL );
  assert( address != NULL );

  if ( !valid_vni( vni ) ) {
    return false;
  }

  char *delete_uri = NULL;
  list_element *reflectors = NULL;
  
  bool ret = get_reflectors_to_update( &reflectors, vni );
  if ( !ret ) {
    error( "Failed to retrieve reflectors information ( vni = %#x ).", vni );
    goto error;
  }

  for ( list_element *e = reflectors; e != NULL; e = e->next ) {
    char *base_uri = e->data;
    size_t delete_uri_length = strlen( base_uri ) + strlen( "reflector/" ) + MAX_VNI_STRLEN  + INET_ADDRSTRLEN;
    delete_uri = xmalloc( delete_uri_length );
    memset( delete_uri, '\0', delete_uri_length );
    snprintf( delete_uri, delete_uri_length, "%sreflector/%u/%s", base_uri, vni & VNI_MASK, address );
    ret = do_http_request( HTTP_METHOD_DELETE, delete_uri, NULL, http_transaction_completed, entry );
    if ( !ret ) {
      error( "Failed to send a HTTP request." );
      entry->n_failed_http_requests++;
      goto error;
    }
    entry->n_ongoing_http_requests++;
    xfree( delete_uri );
  }

  free_list( reflectors );

  return true;

error:
  if ( reflectors != NULL ) {
    free_list( reflectors );
  }
  if ( delete_uri != NULL ) {
    xfree( delete_uri );
  }

  return false;
}
static bool
delete_tunnel_from_tep( transaction_entry *entry, uint32_t vni, uint64_t datapath_id ) {
  debug( "Deleting a virtual network from a tunnel endpoint ( entry = %p, vni = %#x, datapath_id = %#" PRIx64 ").", entry, vni, datapath_id );

  assert( entry != NULL );

  char *base_uri = NULL;
  char *delete_uri = NULL;

  bool ret = get_agent_uri( datapath_id, &base_uri );
  if ( !ret ) {
    error( "Failed to retrieve agent information ( datapath_id = %#" PRIx64 " ).", datapath_id );
    goto error;
  }

  size_t delete_uri_length = strlen( base_uri ) + strlen( "overlay_networks/" ) + MAX_VNI_STRLEN;
  delete_uri = xmalloc( delete_uri_length );
  memset( delete_uri, '\0', delete_uri_length );
  snprintf( delete_uri, delete_uri_length, "%soverlay_networks/%u", base_uri, vni & VNI_MASK );

  ret = do_http_request( HTTP_METHOD_DELETE, delete_uri, NULL, http_transaction_completed, entry );
  if ( !ret ) {
    error( "Failed to send a HTTP request to HTTP client thread ( datapath_id = %" PRIx64 " ).", datapath_id );
    entry->n_failed_http_requests++;
    goto error;
  }
  entry->n_ongoing_http_requests++;

  xfree( base_uri );
  xfree( delete_uri );

  return true;

error:
  if ( base_uri != NULL ) {
    xfree( base_uri );
  }
  if ( delete_uri != NULL ) {
    xfree( delete_uri );
  }

  return false;
}
static bool
add_tunnel_to_tep( transaction_entry *entry, uint32_t vni, uint64_t datapath_id, const char *broadcast_address, uint16_t broadcast_port ) {
  debug( "Adding a virtual network to a tunnel endpoint ( entry = %p, vni = %#x, datapath_id = %#" PRIx64 ", broadcast_address = %s, broadcast_port = %u ).",
         entry, vni, datapath_id, broadcast_address != NULL ? broadcast_address : "", broadcast_port );

  assert( entry != NULL );
  assert( broadcast_address != NULL );

  char *base_uri = NULL;
  char *post_uri = NULL;
  char *json_string = NULL;
  http_content content;

  memset( &content, 0 , sizeof( http_content ) );

  bool ret = get_agent_uri( datapath_id, &base_uri );
  if ( !ret ) {
    error( "Failed to retrieve agent information ( datapath_id = %#" PRIx64 " ).", datapath_id );
    goto error;
  }

  ret = create_json_to_add_tunnel( &json_string, vni, broadcast_address, broadcast_port );
  if ( !ret || json_string == NULL || ( json_string != NULL && strlen( json_string ) == 0 ) ) {
    error( "Failed to create json string for Gate Switch." );
    goto error;
  }

  size_t post_uri_length = strlen( base_uri ) + strlen( "overlay_networks" ) + 1;
  post_uri = xmalloc( post_uri_length );
  memset( post_uri, '\0', post_uri_length );
  snprintf( post_uri, post_uri_length, "%soverlay_networks", base_uri );

  memset( content.content_type, '\0', sizeof( content.content_type ) );
  snprintf( content.content_type, sizeof( content.content_type ), "application/json" );
  size_t json_string_length = strlen( json_string ) + 1;
  content.body = alloc_buffer_with_length( json_string_length );
  void *p = append_back_buffer( content.body, json_string_length );
  memcpy( p, json_string, json_string_length );
  ret = do_http_request( HTTP_METHOD_POST, post_uri, &content, http_transaction_completed, entry );
  if ( !ret ) {
    error( "Failed to send a HTTP request to HTTP client thread ( datapath_id = %" PRIx64 " ).", datapath_id );
    entry->n_failed_http_requests++;
    goto error;
  }
  entry->n_ongoing_http_requests++;

  xfree( base_uri );
  xfree( post_uri );
  xfree( json_string );
  free_buffer( content.body );

  return true;

error:
  if ( base_uri != NULL ) {
    xfree( base_uri );
  }
  if ( post_uri != NULL ) {
    xfree( post_uri );
  }
  if ( json_string != NULL) {
    xfree( json_string );
  }
  if ( content.body != NULL ) {
    free_buffer( content.body );
  }

  return false;
}
static bool
add_tep_to_packet_reflectors( transaction_entry *entry, uint32_t vni, const char *address, uint16_t port ) {
  debug( "Adding a tunnel endpoint to packet reflectors ( entry = %p, vni = %#x, address = %s, port = %u ).",
         entry, vni, address != NULL ? address : "", port );

  assert( entry != NULL );
  assert( address != NULL );
  assert( port > 0 );

  if ( !valid_vni( vni ) ) {
    return false;
  }

  char *post_uri = NULL;
  char *json_string = NULL;
  list_element *reflectors = NULL;
  http_content content;
  memset( &content, 0, sizeof( http_content ) );

  bool ret = get_reflectors_to_update( &reflectors, vni );
  if ( !ret ) {
    error( "Failed to retrieve reflectors information ( vni = %#x ).", vni );
    goto error;
  }

  ret = create_json_to_add_tep( &json_string, address, port );
  if ( !ret || json_string == NULL || ( json_string != NULL && strlen( json_string ) == 0 ) ) {
    error( "Failed to create json string for packet reflector." );
    goto error;
  }

  memset( content.content_type, '\0', sizeof( content.content_type ) );
  snprintf( content.content_type, sizeof( content.content_type ), "application/json" );

  size_t json_string_length = strlen( json_string ) + 1;
  content.body = alloc_buffer_with_length( json_string_length );
  void *p = append_back_buffer( content.body, json_string_length );
  memcpy( p, json_string, json_string_length );

  for ( list_element *e = reflectors; e != NULL; e = e->next ) {
    char *base_uri = e->data;
    size_t post_uri_length = strlen( base_uri ) + strlen( "reflector/" ) + MAX_VNI_STRLEN;
    post_uri = xmalloc( post_uri_length );
    memset( post_uri, '\0', post_uri_length );
    snprintf( post_uri, post_uri_length, "%sreflector/%u", base_uri, vni & VNI_MASK );
    ret = do_http_request( HTTP_METHOD_POST, post_uri, &content, http_transaction_completed, entry );
    if ( !ret ) {
      error( "Failed to send a HTTP request." );
      entry->n_failed_http_requests++;
      goto error;
    }
    entry->n_ongoing_http_requests++;
    xfree( post_uri );
  }

  free_list( reflectors );
  xfree( json_string );
  free_buffer( content.body );

  return true;

error:
  if ( reflectors != NULL ) {
    free_list( reflectors );
  }
  if ( json_string != NULL ) {
    xfree( json_string );
  }
  if ( post_uri != NULL ) {
    xfree( post_uri );
  }
  if ( content.body != NULL ) {
    free_buffer( content.body );
  }

  return false;
}
Exemplo n.º 6
0
static bool update_remote_files(void *param, obs_data_t *remote_file)
{
	struct update_info *info = param;

	struct file_update_data data = {
		.name = obs_data_get_string(remote_file, "name"),
		.version = (int)obs_data_get_int(remote_file, "version")
	};

	enum_files(info->cache_package, newer_than_cache, &data);
	if (!data.newer && data.found)
		return true;

	if (!do_relative_http_request(info, info->remote_url, data.name))
		return true;

	if (info->callback) {
		struct file_download_data download_data;
		bool confirm;

		download_data.name = data.name;
		download_data.version = data.version;
		download_data.buffer.da = info->file_data.da;

		confirm = info->callback(info->param, &download_data);

		info->file_data.da = download_data.buffer.da;

		if (!confirm) {
			info("Update file '%s' (version %d) rejected",
					data.name, data.version);
			return true;
		}
	}

	write_file_data(info, info->temp, data.name);
	replace_file(info->temp, info->cache, data.name);

	info("Successfully updated file '%s' (version %d)",
			data.name, data.version);
	return true;
}

static void update_save_metadata(struct update_info *info)
{
	struct dstr path = { 0 };

	if (!info->etag_remote)
		return;

	dstr_copy(&path, info->cache);
	dstr_cat(&path, "meta.json");

	obs_data_t *data;
	data = obs_data_create();
	obs_data_set_string(data, "etag", info->etag_remote);
	obs_data_save_json(data, path.array);
	obs_data_release(data);
}

static void update_remote_version(struct update_info *info, int cur_version)
{
	int remote_version;
	long response_code;

	if (!do_http_request(info, info->url, &response_code))
		return;

	if (response_code == 304)
		return;

	if (!info->file_data.array || info->file_data.array[0] != '{') {
		warn("Remote package does not exist or is not valid json");
		return;
	}

	update_save_metadata(info);

	info->remote_package = obs_data_create_from_json(
			(char*)info->file_data.array);
	if (!info->remote_package) {
		warn("Failed to initialize remote package json");
		return;
	}

	remote_version = (int)obs_data_get_int(info->remote_package, "version");
	if (remote_version <= cur_version)
		return;

	write_file_data(info, info->temp, "package.json");

	info->remote_url = obs_data_get_string(info->remote_package, "url");
	if (!info->remote_url) {
		warn("No remote url in package file");
		return;
	}

	/* download new files */
	enum_files(info->remote_package, update_remote_files, info);

	replace_file(info->temp, info->cache, "package.json");

	info("Successfully updated package (version %d)", remote_version);
	return;
}