diff --git a/src/mastersrv/master.c b/src/mastersrv/master.c
index 6bb4ffd22ef92de2ae8e551a4a32c1d0d948f2b1..c68d59c1042f9b090632971b5e696648df28ec3e 100644 (file)
--- a/src/mastersrv/master.c
+++ b/src/mastersrv/master.c
banlist = NULL;
}
+static bool ban_record_remove_addr(const enet_uint32 host, const enet_uint32 mask) {
+ for (ban_record_t *b = banlist; b; b = b->next) {
+ if ((b->host == host) && (b->mask == mask)) {
+ if (b == banlist)
+ banlist = b->next;
+ if (b->next) b->next->prev = b->prev;
+ if (b->prev) b->prev->next = b->next;
+ free(b);
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool ban_record_remove_ip(const char *ip) {
+ enet_uint32 mask = 0;
+ const enet_uint32 host = ban_parse_ip_mask(ip, &mask);
+ if (!host) {
+ u_log(LOG_ERROR, "unban: `%s` is not a valid address", ip);
+ return NULL;
+ }
+ return ban_record_remove_addr(host, mask);
+}
+
static void ban_load_list(const char *fname) {
FILE *f = fopen(fname, "r");
if (!f) {
continue;
char ip[21] = { 0 }; // optionally includes the "/nn" prefix length at the end
- int64_t exp64 = 0;
+ int expd = 0;
int count = 0;
- if (sscanf(ln, "%20s %lld %d", ip, &exp64, &count) < 3) {
+ if (sscanf(ln, "%20s %d %d", ip, &expd, &count) < 3) {
u_log(LOG_ERROR, "banlist: malformed line: `%s`", ln);
continue;
}
- const time_t exp = (time_t)exp64; // shut up gcc
+ const time_t exp = (time_t)expd; // shut up gcc
if (ban_record_add_ip(ip, count, exp))
u_log(LOG_NOTE, "banlist: banned %s until %s (ban level %d)", ip, u_strtime(exp), count);
}
for (ban_record_t *rec = banlist; rec; rec = rec->next) {
if (rec->ban_count)
- fprintf(f, "%s/%u %lld %d\n", u_iptostr(rec->host), u_masktoprefix(rec->mask), (int64_t)rec->cur_ban, rec->ban_count);
+ fprintf(f, "%s/%u %d %d\n", u_iptostr(rec->host), u_masktoprefix(rec->mask), (int)rec->cur_ban, rec->ban_count);
}
fclose(f);
cl_last_addr = 0;
}
+static void ban_remove_mask(const enet_uint32 host, const enet_uint32 mask) {
+ if (!ban_record_remove_addr(host, mask)) {
+ u_log(LOG_ERROR, "could not find %s in ban list", u_iptostr(host));
+ return;
+ }
+ u_log(LOG_NOTE, "unbanned %s", u_iptostr(host));
+ ban_save_list(MS_BAN_FILE);
+}
+
static inline void ban_peer(ENetPeer *peer, const char *reason) {
if (peer) {
ban_add(peer->address.host, reason);
return;
}
ban_add_mask(host, mask, "banned by console");
+ } else if (!strncmp(cmd, "unban ", 6)) {
+ const char *ip = u_strstrip(cmd + 6); // skip "unban "
+ enet_uint32 mask = 0;
+ enet_uint32 host = ban_parse_ip_mask(ip, &mask);
+ if (!host) {
+ u_log(LOG_ERROR, "ban: `%s` is not a valid address", ip);
+ return;
+ }
+ ban_remove_mask(host, mask);
} else if (!strncmp(cmd, "reload", 6)) {
u_log(LOG_WARN, "reloading banlist");
ban_free_list();