Index: libfdcore/config.c
===================================================================
--- libfdcore/config.c	(revision 1396)
+++ libfdcore/config.c	(revision 1397)
@@ -62,4 +62,9 @@
 	fd_g_config->cnf_processing_peers_minimum = 0;
 	fd_g_config->cnf_dispthr  = 4;
+	fd_g_config->cnf_rtinthr = 1;
+	fd_g_config->cnf_rtoutthr = 1;
+	fd_g_config->cnf_qin_limit = 20;
+	fd_g_config->cnf_qout_limit = 30;
+	fd_g_config->cnf_qlocal_limit = 25;
 	fd_list_init(&fd_g_config->cnf_endpoints, NULL);
 	fd_list_init(&fd_g_config->cnf_apps, NULL);
@@ -104,4 +109,9 @@
 	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Number of app threads .. : %hu\n", fd_g_config->cnf_dispthr), return NULL);
 	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Minimal processing peers : %hu\n", fd_g_config->cnf_processing_peers_minimum), return NULL);
+	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Number of rtin threads . : %hu\n", fd_g_config->cnf_rtinthr), return NULL);
+	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Number of rtout threads  : %hu\n", fd_g_config->cnf_rtoutthr), return NULL);
+	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Incoming queue limit     : %hu\n", fd_g_config->cnf_qin_limit), return NULL);
+	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Outgoing queue limit     : %hu\n", fd_g_config->cnf_qout_limit), return NULL);
+	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local queue limit        : %hu\n", fd_g_config->cnf_qlocal_limit), return NULL);
 	if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) {
 		CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local endpoints ........ : Default (use all available)\n"), return NULL);
Index: libfdcore/core.c
===================================================================
--- libfdcore/core.c	(revision 1325)
+++ libfdcore/core.c	(revision 1397)
@@ -316,4 +316,6 @@
 {
 	int ret;
+	CHECK_FCT( fd_queues_init_after_conf() );
+
 	CHECK_POSIX( pthread_mutex_lock(&core_lock) );
 	ret = fd_core_start_int();
Index: libfdcore/fdcore-internal.h
===================================================================
--- libfdcore/fdcore-internal.h	(revision 1240)
+++ libfdcore/fdcore-internal.h	(revision 1397)
@@ -110,4 +110,5 @@
 /* Message queues */
 int fd_queues_init(void);
+int fd_queues_init_after_conf(void);
 int fd_queues_fini(struct fifo ** queue);
 
Index: libfdcore/fdd.l
===================================================================
--- libfdcore/fdd.l	(revision 1396)
+++ libfdcore/fdd.l	(revision 1397)
@@ -255,4 +255,9 @@
 (?i:"SCTP_streams")	{ return SCTPSTREAMS; }
 (?i:"AppServThreads")	{ return APPSERVTHREADS; }
+(?i:"RoutingInThreads")	{ return ROUTINGINTHREADS; }
+(?i:"RoutingOutThreads")	{ return ROUTINGOUTTHREADS; }
+(?i:"IncomingQueueLimit")	{ return QINLIMIT; }
+(?i:"OutgoingQueueLimit")	{ return QOUTLIMIT; }
+(?i:"LocalQueueLimit")	{ return QLOCALLIMIT; }
 (?i:"ListenOn")		{ return LISTENON; }
 (?i:"ThreadsPerServer")	{ return THRPERSRV; }
@@ -272,4 +277,7 @@
 (?i:"TLS_DH_bits")	{ return TLS_DH_BITS; }
 (?i:"TLS_DH_file")	{ return TLS_DH_FILE; }
+(?i:"RouteRecordInAnswers")	{ return RR_IN_ANSWERS;	}
+(?i:"Never")		{ return NEVER;	}
+(?i:"Always")		{ return ALWAYS; }
 
 
Index: libfdcore/fdd.y
===================================================================
--- libfdcore/fdd.y	(revision 1396)
+++ libfdcore/fdd.y	(revision 1397)
@@ -108,4 +108,9 @@
 %token		SCTPSTREAMS
 %token		APPSERVTHREADS
+%token		ROUTINGINTHREADS
+%token		ROUTINGOUTTHREADS
+%token		QINLIMIT
+%token		QOUTLIMIT
+%token		QLOCALLIMIT
 %token		LISTENON
 %token		THRPERSRV
@@ -148,4 +153,9 @@
 			| conffile norelay
 			| conffile appservthreads
+			| conffile routinginthreads
+			| conffile routingoutthreads
+			| conffile qinlimit
+			| conffile qoutlimit
+			| conffile qlocallimit
 			| conffile noip
 			| conffile noip6
@@ -307,4 +317,44 @@
 					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
 				conf->cnf_dispthr = (uint16_t)$3;
+			}
+			;
+
+routinginthreads:		ROUTINGINTHREADS '=' INTEGER ';'
+			{
+				CHECK_PARAMS_DO( ($3 > 0) && ($3 < 256),
+					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
+				conf->cnf_rtinthr = (uint16_t)$3;
+			}
+			;
+
+routingoutthreads:		ROUTINGOUTTHREADS '=' INTEGER ';'
+			{
+				CHECK_PARAMS_DO( ($3 > 0) && ($3 < 256),
+					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
+				conf->cnf_rtoutthr = (uint16_t)$3;
+			}
+			;
+
+qinlimit:		QINLIMIT '=' INTEGER ';'
+			{
+				CHECK_PARAMS_DO( ($3 >= 0),
+					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
+				conf->cnf_qin_limit = $3;
+			}
+			;
+
+qoutlimit:		QOUTLIMIT '=' INTEGER ';'
+			{
+				CHECK_PARAMS_DO( ($3 >= 0),
+					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
+				conf->cnf_qout_limit = $3;
+			}
+			;
+
+qlocallimit:		QLOCALLIMIT '=' INTEGER ';'
+			{
+				CHECK_PARAMS_DO( ($3 >= 0),
+					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
+				conf->cnf_qlocal_limit = $3;
 			}
 			;
Index: libfdcore/queues.c
===================================================================
--- libfdcore/queues.c	(revision 1127)
+++ libfdcore/queues.c	(revision 1397)
@@ -45,7 +45,17 @@
 {
 	TRACE_ENTRY();
-	CHECK_FCT( fd_fifo_new ( &fd_g_incoming, 20 ) );
-	CHECK_FCT( fd_fifo_new ( &fd_g_outgoing, 30 ) );
-	CHECK_FCT( fd_fifo_new ( &fd_g_local, 25 ) );
+	CHECK_FCT( fd_fifo_new ( &fd_g_incoming, fd_g_config->cnf_qin_limit ) );
+	CHECK_FCT( fd_fifo_new ( &fd_g_outgoing, fd_g_config->cnf_qout_limit ) );
+	CHECK_FCT( fd_fifo_new ( &fd_g_local,    fd_g_config->cnf_qlocal_limit ) );
+	return 0;
+}
+
+/* Resize according to values given in configuration file */
+int fd_queues_init_after_conf(void)
+{
+	TRACE_ENTRY();
+	CHECK_FCT( fd_fifo_set_max ( fd_g_incoming, fd_g_config->cnf_qin_limit ) );
+	CHECK_FCT( fd_fifo_set_max ( fd_g_outgoing, fd_g_config->cnf_qout_limit ) );
+	CHECK_FCT( fd_fifo_set_max ( fd_g_local,    fd_g_config->cnf_qlocal_limit ) );
 	return 0;
 }
Index: libfdcore/routing_dispatch.c
===================================================================
--- libfdcore/routing_dispatch.c	(revision 1328)
+++ libfdcore/routing_dispatch.c	(revision 1397)
@@ -35,4 +35,11 @@
 
 #include "fdcore-internal.h"
+
+#ifdef linux
+/* This needs -D_USE_GNU, and since I have no idea what else that does, let's simply copy the declaration. */
+
+/* Set thread name visible in the kernel and its interfaces.  */
+extern int pthread_setname_np (pthread_t __target_thread, const char *__name);
+#endif
 
 /********************************************************************************/
@@ -1153,10 +1160,9 @@
 static enum thread_state * disp_state = NULL;
 
-/* Later: make this more dynamic */
-static pthread_t rt_out = (pthread_t)NULL;
-static enum thread_state out_state = NOTRUNNING;
-
-static pthread_t rt_in  = (pthread_t)NULL;
-static enum thread_state in_state = NOTRUNNING;
+static pthread_t * rt_out = NULL;
+static enum thread_state * out_state = NULL;
+
+static pthread_t * rt_in  = NULL;
+static enum thread_state * in_state = NULL;
 
 /* Initialize the routing and dispatch threads */
@@ -1165,14 +1171,31 @@
 	int i;
 	
-	/* Prepare the array for dispatch */
+	/* Prepare the array for threads */
 	CHECK_MALLOC( disp_state = calloc(fd_g_config->cnf_dispthr, sizeof(enum thread_state)) );
 	CHECK_MALLOC( dispatch = calloc(fd_g_config->cnf_dispthr, sizeof(pthread_t)) );
+	CHECK_MALLOC( out_state = calloc(fd_g_config->cnf_rtoutthr, sizeof(enum thread_state)) );
+	CHECK_MALLOC( rt_out = calloc(fd_g_config->cnf_rtoutthr, sizeof(pthread_t)) );
+	CHECK_MALLOC( in_state = calloc(fd_g_config->cnf_rtinthr, sizeof(enum thread_state)) );
+	CHECK_MALLOC( rt_in = calloc(fd_g_config->cnf_rtinthr, sizeof(pthread_t)) );
 	
 	/* Create the threads */
 	for (i=0; i < fd_g_config->cnf_dispthr; i++) {
 		CHECK_POSIX( pthread_create( &dispatch[i], NULL, dispatch_thr, &disp_state[i] ) );
-	}
-	CHECK_POSIX( pthread_create( &rt_out, NULL, routing_out_thr, &out_state) );
-	CHECK_POSIX( pthread_create( &rt_in,  NULL, routing_in_thr,  &in_state) );
+#ifdef linux
+		pthread_setname_np(dispatch[i], "fd-dispatch");
+#endif
+	}
+	for (i=0; i < fd_g_config->cnf_rtoutthr; i++) {
+		CHECK_POSIX( pthread_create( &rt_out[i], NULL, routing_out_thr, &out_state[i] ) );
+#ifdef linux
+		pthread_setname_np(rt_out[i], "fd-routing-out");
+#endif
+	}
+	for (i=0; i < fd_g_config->cnf_rtinthr; i++) {
+		CHECK_POSIX( pthread_create( &rt_in[i], NULL, routing_in_thr, &in_state[i] ) );
+#ifdef linux
+		pthread_setname_np(rt_in[i], "fd-routing-in");
+#endif
+	}
 	
 	/* Later: TODO("Set the thresholds for the queues to create more threads as needed"); */
@@ -1245,5 +1268,15 @@
 	
 	/* Stop the routing IN thread */
-	stop_thread_delayed(&in_state, &rt_in, "IN routing");
+	if (rt_in != NULL) {
+		for (i=0; i < fd_g_config->cnf_rtinthr; i++) {
+			stop_thread_delayed(&in_state[i], &rt_in[i], "IN routing");
+		}
+		free(rt_in);
+		rt_in = NULL;
+	}
+	if (in_state != NULL) {
+		free(in_state);
+		in_state = NULL;
+	}
 	
 	/* Destroy the outgoing queue */
@@ -1251,5 +1284,15 @@
 	
 	/* Stop the routing OUT thread */
-	stop_thread_delayed(&out_state, &rt_out, "OUT routing");
+	if (rt_out != NULL) {
+		for (i=0; i < fd_g_config->cnf_rtinthr; i++) {
+			stop_thread_delayed(&out_state[i], &rt_out[i], "OUT routing");
+		}
+		free(rt_out);
+		rt_out = NULL;
+	}
+	if (out_state != NULL) {
+		free(out_state);
+		out_state = NULL;
+	}
 	
 	/* Destroy the local queue */
