X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fmastersrv%2Fmaster.c;h=c68d59c1042f9b090632971b5e696648df28ec3e;hb=5a9d04dfb16b32c84964c0940031606e7454259d;hp=6bb4ffd22ef92de2ae8e551a4a32c1d0d948f2b1;hpb=c0ad7dea5d7ab3f8f4b49f765d698e5e5aece153;p=d2df-sdl.git diff --git a/src/mastersrv/master.c b/src/mastersrv/master.c index 6bb4ffd..c68d59c 100644 --- a/src/mastersrv/master.c +++ b/src/mastersrv/master.c @@ -549,6 +549,30 @@ static void ban_free_list(void) { 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) { @@ -567,14 +591,14 @@ static void ban_load_list(const char *fname) { 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); } @@ -591,7 +615,7 @@ static void ban_save_list(const char *fname) { 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); @@ -657,6 +681,15 @@ static void ban_add(const enet_uint32 host, const char *reason) { 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); @@ -715,6 +748,15 @@ static void io_read_commands(void) { 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();