as.c 2.73 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
/*
	libloc - A library to determine the location of someone on the Internet

	Copyright (C) 2017 IPFire Development Team <info@ipfire.org>

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.
*/

#include <arpa/inet.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>

#include <loc/libloc.h>
#include <loc/format.h>

#include "libloc-private.h"
#include "as.h"
#include "stringpool.h"

struct loc_as {
	struct loc_ctx* ctx;
	int refcount;

	struct loc_stringpool* pool;

	uint32_t number;
	off_t name;
};

LOC_EXPORT int loc_as_new(struct loc_ctx* ctx, struct loc_stringpool* pool, struct loc_as** as, uint32_t number) {
	struct loc_as* a = calloc(1, sizeof(*a));
	if (!a)
		return -ENOMEM;

	a->ctx = loc_ref(ctx);
	a->refcount = 1;
	a->pool = loc_stringpool_ref(pool);

	a->number = number;

	DEBUG(a->ctx, "AS%u allocated at %p\n", a->number, a);
	*as = a;

	return 0;
}

LOC_EXPORT struct loc_as* loc_as_ref(struct loc_as* as) {
	as->refcount++;

	return as;
}

static void loc_as_free(struct loc_as* as) {
	DEBUG(as->ctx, "Releasing AS%u %p\n", as->number, as);

	loc_stringpool_unref(as->pool);
	loc_unref(as->ctx);

	free(as);
}

LOC_EXPORT struct loc_as* loc_as_unref(struct loc_as* as) {
	if (--as->refcount > 0)
		return NULL;

	loc_as_free(as);

	return NULL;
}

LOC_EXPORT uint32_t loc_as_get_number(struct loc_as* as) {
	return as->number;
}

LOC_EXPORT const char* loc_as_get_name(struct loc_as* as) {
	return loc_stringpool_get(as->pool, as->name);
}

LOC_EXPORT int loc_as_set_name(struct loc_as* as, const char* name) {
	// Add the string to the string pool
	off_t offset = loc_stringpool_add(as->pool, name);
	if (offset < 0)
		return offset;

	as->name = offset;
	return 0;
}

LOC_EXPORT int loc_as_cmp(struct loc_as* as1, struct loc_as* as2) {
	if (as1->number > as2->number)
		return 1;

	if (as1->number < as2->number)
		return -1;

	return 0;
}

int loc_as_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool,
		struct loc_as** as, const struct loc_database_as_v0* dbobj) {
	uint32_t number = ntohl(dbobj->number);

	int r = loc_as_new(ctx, pool, as, number);
	if (r)
		return r;

	(*as)->name = ntohl(dbobj->name);

	return 0;
}

int loc_as_to_database_v0(struct loc_as* as, struct loc_database_as_v0* dbobj) {
	dbobj->number = htonl(as->number);
	dbobj->name   = htonl(as->name);

	return 0;
}