#ifdef USE_DST_BLACKLIST
void dst_blst_debug(rpc_t* rpc, void* ctx);
void dst_blst_mem_info(rpc_t* rpc, void* ctx);
+void dst_blst_view(rpc_t* rpc, void* ctx);
+void dst_blst_delete_all(rpc_t* rpc, void* ctx);
+void dst_blst_add(rpc_t* rpc, void* ctx);
static const char* dst_blst_mem_info_doc[] = {
"dst blacklist memory usage info.", /* Documentation string */
"dst blacklist debug info.", /* Documentation string */
0 /* Method signature(s) */
};
+static const char* dst_blst_view_doc[] = {
+ "dst blacklist dump in human-readable format.", /* Documentation string */
+ 0 /* Method signature(s) */
+};
+static const char* dst_blst_delete_all_doc[] = {
+ "Deletes all the entries from the dst blacklist except the permanent ones.", /* Documentation string */
+ 0 /* Method signature(s) */
+};
+static const char* dst_blst_add_doc[] = {
+ "Adds a new entry to the dst blacklist.", /* Documentation string */
+ 0 /* Method signature(s) */
+};
+
#endif
#ifdef USE_DST_BLACKLIST
{"dst_blacklist.mem_info", dst_blst_mem_info, dst_blst_mem_info_doc, 0 },
{"dst_blacklist.debug", dst_blst_debug, dst_blst_debug_doc, 0 },
+ {"dst_blacklist.view", dst_blst_view, dst_blst_view_doc, 0 },
+ {"dst_blacklist.delete_all", dst_blst_delete_all, dst_blst_delete_all_doc, 0 },
+ {"dst_blacklist.add", dst_blst_add, dst_blst_add_doc, 0 },
#endif
{0, 0, 0, 0}
};
#include "error.h"
#include "rpc.h"
#include "compiler_opt.h"
+#include "resolve.h" /* for str2ip */
}
}
+/* dumps the content of the blacklist in a human-readable format */
+void dst_blst_view(rpc_t* rpc, void* ctx)
+{
+ int h;
+ struct dst_blst_entry* e;
+ ticks_t now;
+ struct ip_addr ip;
+ void* handle;
+
+ now=get_ticks_raw();
+ for(h=0; h<DST_BLST_HASH_SIZE; h++){
+ LOCK_BLST(h);
+ for(e=dst_blst_hash[h].first; e; e=e->next){
+ rpc->add(ctx, "{", &handle);
+ dst_blst_entry2ip(&ip, e);
+ rpc->struct_add(handle, "s", "protocol",
+ get_proto_name(e->proto));
+ rpc->struct_add(handle, "s", "ip",
+ ip_addr2a(&ip));
+ rpc->struct_add(handle, "d", "port",
+ e->port);
+ rpc->struct_add(handle, "d", "expires in (s)",
+ (s_ticks_t)(now-e->expire)<=0?
+ TICKS_TO_S(e->expire-now):
+ -TICKS_TO_S(now-e->expire));
+ rpc->struct_add(handle, "d", "flags",
+ e->flags);
+ }
+ UNLOCK_BLST(h);
+ }
+}
+
+/* deletes all the entries from the blacklist except the permanent ones
+ * (which are marked with BLST_PERMANENT)
+ */
+void dst_blst_flush(void)
+{
+ int h;
+ struct dst_blst_entry* e;
+ struct dst_blst_entry** last;
+
+ for(h=0; h<DST_BLST_HASH_SIZE; h++){
+ LOCK_BLST(h);
+ last = &dst_blst_hash[h].first;
+ for(e=dst_blst_hash[h].first; e; e=e->next){
+ if (e->flags & BLST_PERMANENT) {
+ /* permanent entry, do not remove it from the list */
+ *last = e;
+ last = &e->next;
+ } else {
+ /* remove the entry from the list */
+ *blst_mem_used-=DST_BLST_ENTRY_SIZE(*e);
+ blst_destroy_entry(e);
+ BLST_HASH_STATS_DEC(h);
+ }
+ }
+ *last = NULL;
+ UNLOCK_BLST(h);
+ }
+}
+
+/* rpc wrapper function for dst_blst_flush() */
+void dst_blst_delete_all(rpc_t* rpc, void* ctx)
+{
+ dst_blst_flush();
+}
+
+/* Adds a new entry to the blacklist */
+void dst_blst_add(rpc_t* rpc, void* ctx)
+{
+ str ip;
+ int port, proto, flags;
+ unsigned char err_flags;
+ struct ip_addr *ip_addr;
+
+ if (rpc->scan(ctx, "Sddd", &ip, &port, &proto, &flags) < 4)
+ return;
+
+ err_flags = (unsigned char)flags;
+ /* sanity checks */
+ if ((unsigned char)proto > PROTO_SCTP) {
+ rpc->fault(ctx, 400, "Unknown protocol");
+ return;
+ }
+
+ if (err_flags & BLST_IS_IPV6) {
+ /* IPv6 address is specified */
+ ip_addr = str2ip6(&ip);
+ } else {
+ /* try IPv4 first, than IPv6 */
+ ip_addr = str2ip(&ip);
+ if (!ip_addr) {
+ ip_addr = str2ip6(&ip);
+ err_flags |= BLST_IS_IPV6;
+ }
+ }
+ if (!ip_addr) {
+ rpc->fault(ctx, 400, "Malformed ip address");
+ return;
+ }
+
+ if (dst_blacklist_add_ip(err_flags, proto, ip_addr, port))
+ rpc->fault(ctx, 400, "Failed to add the entry to the blacklist");
+}
#endif /* USE_DST_BLACKLIST */