diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/config/mingw/mlUnix.ml ./src/config/mingw/mlUnix.ml
--- ./src/config/mingw/mlUnix.ml	2005-12-02 13:08:26.000000000 +0100
+++ ./src/config/mingw/mlUnix.ml	2005-12-28 19:43:38.000000000 +0100
@@ -68,9 +68,6 @@
 let set_close_on_exec fd = ()
 let set_signal signal f = Sys.set_signal signal f
   
-external getdtablesize : unit -> int = "ml_getdtablesize"
-  
-let max_sockets = getdtablesize () - 10
 let max_filedescs = 50
   
 let chroot _ = ()
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/config/unix/mlUnix.ml ./src/config/unix/mlUnix.ml
--- ./src/config/unix/mlUnix.ml	2005-12-14 22:17:46.000000000 +0100
+++ ./src/config/unix/mlUnix.ml	2005-12-28 19:43:38.000000000 +0100
@@ -97,13 +97,6 @@
 let set_close_on_exec = Unix.set_close_on_exec
 let set_signal signal f = Sys.set_signal signal f
   
-  
-external getdtablesize : unit -> int = "ml_getdtablesize"
-  
-let max_all_sockets = getdtablesize ()
-let max_sockets = max (max_all_sockets - 100) (max_all_sockets / 2)
-let max_filedescs = (max_all_sockets - max_sockets) / 2
-
 let chroot = Unix.chroot  
 
 let write = Unix.write
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/daemon/common/commonComplexOptions.ml ./src/daemon/common/commonComplexOptions.ml
--- ./src/daemon/common/commonComplexOptions.ml	2005-12-28 11:36:26.000000000 +0100
+++ ./src/daemon/common/commonComplexOptions.ml	2005-12-28 19:51:27.000000000 +0100
@@ -1270,3 +1270,60 @@
     	) !list;
   if o.conn_output = HTML then
     Printf.bprintf buf "\\</table\\>\\</td\\>\\<tr\\>\\</table\\>\\</div\\>"
+
+let _ =
+  option_hook max_opened_connections (fun _ ->
+  if !verbose then lprintf_nl ()
+    "checking max_opened_connections = %d for validity" !!max_opened_connections;
+(* original code from ./src/config/unix/MlUnix.ml
+let max_all_sockets = getdtablesize ()
+let max_sockets = max (max_all_sockets - 100) (max_all_sockets / 2)
+let max_filedescs = (max_all_sockets - max_sockets) / 2 *)
+
+  (* ulimit open files. minimum 150, most systems have 1024 *)
+  let max_all_sockets = Unix2.c_getdtablesize () in
+
+  (* old max_sockets code: max (150 - 100) (150 / 2),
+     minimum number of max_opened_connections *)
+  let min_conns = 75 in
+
+  if min_conns > !!max_opened_connections then begin
+    lprintf_nl () "max_opened_connections is set too low (%d), raising to %d"
+      !!max_opened_connections min_conns;
+    max_opened_connections =:= min_conns
+  end;
+
+  let total_files = (* maximum number of files in use at the same time *)
+    (maxi (List.length !!files) !!max_concurrent_downloads) + !!max_upload_slots + 20 (* ini files etc. *)
+  in
+
+  let wanted_socks = !!max_opened_connections + total_files in
+
+  if max_all_sockets < wanted_socks then
+    if max_all_sockets < total_files + min_conns then (* check if ulimit is enough to allow total_files + min_conns *)
+      begin
+        lprintf_nl () "only %d file descriptors available, raise ulimit open files to at least %d"
+          max_all_sockets wanted_socks;
+        lprintf_nl () "FD info: max_opened_connections %d, number of (possible) concurrent downloads %d, = %d fd needed"
+          !!max_opened_connections total_files wanted_socks;
+        CommonGlobals.exit_properly 71
+      end
+  else
+    begin
+      let new_max_opened_connections =
+        maxi (max_all_sockets - total_files) (max_all_sockets / 2)
+      in
+      lprintf_nl () "max_opened_connections is set too high (%d), reducing to %d"
+        !!max_opened_connections new_max_opened_connections;
+      max_opened_connections =:= new_max_opened_connections;
+    end;
+
+  if !verbose then lprintf_nl ()
+    "max_opened_connections %d, total_files %d, max_concurrent_downloads %d, !!files %d"
+      !!max_opened_connections total_files !!max_concurrent_downloads (List.length !!files);
+
+  TcpBufferedSocket.set_max_opened_connections
+    (fun _ -> !!max_opened_connections);
+
+  Unix32.max_cache_size := total_files - 20
+)
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/daemon/common/commonOptions.ml ./src/daemon/common/commonOptions.ml
--- ./src/daemon/common/commonOptions.ml	2005-12-28 11:38:34.000000000 +0100
+++ ./src/daemon/common/commonOptions.ml	2005-12-28 19:43:38.000000000 +0100
@@ -106,10 +106,15 @@
 
 let _ =
   lprintf_nl "Starting MLDonkey %s ... " Autoconf.current_version;
-  lprintf_nl "Language %s, locale %s"
-    Charset.default_language Charset.locstr;
+  lprintf_nl "Language %s, locale %s, ulimit for open files %d"
+    Charset.default_language Charset.locstr (Unix2.c_getdtablesize ());
   lprintf_nl "MLDonkey is working in %s" file_basedir;
 
+  let ulof = Unix2.c_getdtablesize () in
+  if ulof < 150 then begin
+    lprintf_nl "ulimit for open files is set to %d, at least 150 is required, exiting..." ulof;
+    exit 2
+  end;
   (try
      Unix2.safe_mkdir file_basedir
    with e ->
@@ -421,7 +426,38 @@
     "exit", "q";
   ]
 
-
+let verbosity = define_expert_option current_section ["verbosity"]
+  "A space-separated list of keywords. Each keyword triggers
+  printing information on the corresponding messages:
+  verb : verbose mode (interesting not only for coders)
+  mc : debug client messages
+  mr|raw : debug raw messages
+  mct : debug emule clients tags
+  ms : debug server messages
+  sm : debug source management
+  net : debug net
+  gui : debug gui
+  do : some download warnings
+  up : some upload warnings
+  unk : unknown messages
+  ov : overnet
+  loc : debug source research
+  share: debug sharing
+  md4 : md4 computation
+  connect : debug connections
+  udp : udp messages
+  ultra|super : debug supernode
+  swarming : debug swarming
+  hc : http_client messages
+  hs : http_server messages
+  act : debug activity
+  bw : debug bandwidth
+  tor : debug .torrent loading
+  file : debug file handling
+  redir : debug redirector
+  unexp : debug unexpected messages
+"
+    string_option ""
 
 
 (*************************************************************************)
@@ -442,11 +478,14 @@
   The limit will apply on all your connections (clients and servers) and both
 control and data messages." int_option 50
 
-
 let max_opened_connections = define_option current_section
     ["max_opened_connections"] "Maximal number of opened connections"
-  int_option (min MlUnix.max_sockets 200)
+  int_option 200
 
+let max_indirect_connections = define_option current_section
+    ["max_indirect_connections"]
+  "Amount of indirect connections in percent (max 50) of max_opened_connections, additional to max_opened_connections"
+  int_option 20
 
 let max_upload_slots = define_option current_section ["max_upload_slots"]
     "How many slots can be used for upload"
@@ -940,7 +979,7 @@
 let max_concurrent_downloads = define_option current_section
     ["max_concurrent_downloads"]
   "The maximal number of files in Downloading state (other ones are Queued)"
-    int_option 60
+    int_option 50
 
 let sources_per_chunk =
   define_expert_option current_section ["sources_per_chunk"]
@@ -1454,38 +1493,6 @@
     also enable logging in a file after startup using the 'log_file' command."
   string_option "mlnet.log"
 
-let verbosity = define_expert_option current_section ["verbosity"]
-  "A space-separated list of keywords. Each keyword triggers
-  printing information on the corresponding messages:
-  mc : debug client messages
-  mr|raw : debug raw messages
-  mct : debug emule clients tags
-  ms : debug server messages
-  verb : debug other
-  sm : debug source management
-  net : debug net
-  gui : debug gui
-  do : some download warnings
-  up : some upload warnings
-  unk : unknown messages
-  ov : overnet
-  loc : debug source research
-  share: debug sharing
-  md4 : md4 computation
-  connect : debug connections
-  udp : udp messages
-  ultra|super : debug supernode
-  swarming : debug swarming
-  hc : http_client messages
-  hs : http_server messages
-  act : debug activity
-  bw : debug bandwidth
-  tor : debug .torrent loading
-  file : debug file handling
-  redir : debug redirector
-  unexp : debug unexpected messages
-"
-    string_option ""
 
 
 
@@ -1867,4 +1874,9 @@
         ];
       update 5
 
+  | 5 ->
+      if !!max_indirect_connections > 50 then
+          max_indirect_connections =:= 20;
+      update 6
+
   | _ -> ()
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/daemon/common/commonSources.ml ./src/daemon/common/commonSources.ml
--- ./src/daemon/common/commonSources.ml	2005-12-14 22:22:07.000000000 +0100
+++ ./src/daemon/common/commonSources.ml	2005-12-28 19:43:38.000000000 +0100
@@ -2216,6 +2216,9 @@
                ((fun (_,_,_,_,_,n) -> n)(H.stats sources_by_num))
                ;
 
+            Printf.bprintf buf "Used indirect connections: %d\n"
+              !indirect_connections;
+
             let nconnected = ref 0 in
             Fifo.iter (fun (_,s) ->
                 if s.source_last_attempt = 0 then incr nconnected;
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/daemon/driver/driverMain.ml ./src/daemon/driver/driverMain.ml
--- ./src/daemon/driver/driverMain.ml	2005-12-24 03:36:09.000000000 +0100
+++ ./src/daemon/driver/driverMain.ml	2005-12-28 19:43:38.000000000 +0100
@@ -449,8 +449,6 @@
   CommonOptions.start_running_plugins := true;
   CommonInteractive.force_download_quotas ();
 
-  TcpBufferedSocket.set_max_opened_connections
-    (fun _ -> !!max_opened_connections);
   TcpBufferedSocket.set_max_connections_per_second
     (fun _ -> !!max_connections_per_second);
 
@@ -552,9 +550,7 @@
     (Sys.Signal_handle (fun _ -> lprintf_nl "Received SIGTERM, stopping MLDonkey...";
         CommonInteractive.clean_exit 0));
 
-  if !verbose then lprintf_nl (_b "Activated system signal handling");
-
-  Unix32.max_cache_size := MlUnix.max_filedescs
+  if !verbose then lprintf_nl (_b "Activated system signal handling")
 
 let _ =
   let security_space_filename = "config_files_space.tmp" in
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/networks/donkey/donkeyClient.ml ./src/networks/donkey/donkeyClient.ml
--- ./src/networks/donkey/donkeyClient.ml	2005-12-24 03:36:09.000000000 +0100
+++ ./src/networks/donkey/donkeyClient.ml	2005-12-28 19:43:38.000000000 +0100
@@ -2398,17 +2398,13 @@
     ) t.Q.locs;
   with Not_found -> ()
       
-let can_open_indirect_connection () =
-  let ns = nb_sockets () in
-  ns < MlUnix.max_sockets &&
-  !DonkeySources.indirect_connections < !!max_indirect_connections
-
 let client_connection_handler overnet t event =
 (*  lprintf "[REMOTE CONN]\n"; *)
   match event with
     TcpServerSocket.CONNECTION (s, Unix.ADDR_INET (from_ip, from_port)) ->
       let from_ip = (Ip.of_inet_addr from_ip) in
-      if can_open_indirect_connection () &&
+      if !DonkeySources.indirect_connections <
+         !!max_opened_connections * !!max_indirect_connections / 100 &&
         (match Ip_set.match_ip !Ip_set.bl from_ip with
                    None -> true
                  | Some br ->
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/networks/donkey/donkeyGlobals.ml ./src/networks/donkey/donkeyGlobals.ml
--- ./src/networks/donkey/donkeyGlobals.ml	2005-12-18 15:50:38.000000000 +0100
+++ ./src/networks/donkey/donkeyGlobals.ml	2005-12-28 19:43:38.000000000 +0100
@@ -61,7 +61,7 @@
   ]
 
 let connection_manager = network.network_connection_manager
-let connections_controler = TcpServerSocket.create_connections_contoler
+let connections_controler = TcpServerSocket.create_connections_controler
     "Edonkey" (fun _ _ -> true)
 
 let (shared_ops : file CommonShared.shared_ops) =
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/networks/donkey/donkeyOptions.ml ./src/networks/donkey/donkeyOptions.ml
--- ./src/networks/donkey/donkeyOptions.ml	2005-12-18 15:50:38.000000000 +0100
+++ ./src/networks/donkey/donkeyOptions.ml	2005-12-28 19:43:38.000000000 +0100
@@ -130,11 +130,6 @@
     ["max_source_age"] "Sources that have not been connected for this number of days are removed"
     int_option 3 *)
 
-let max_indirect_connections = define_option donkey_section
-    ["max_indirect_connections"]
-  "Maximal number of indirect connections at any moment"
-  int_option (!!max_opened_connections/2)
-
 let log_clients_on_console = define_expert_option donkey_section
   ["log_clients_on_console"]
   ""
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/store.ml ./src/utils/lib/store.ml
--- ./src/utils/lib/store.ml	2005-09-03 00:39:59.000000000 +0200
+++ ./src/utils/lib/store.ml	2005-12-28 19:43:38.000000000 +0100
@@ -129,8 +129,6 @@
 
 (********************** STORE FUNCTIONS *****************)
   
-let max_cache_size = 2000
-  
 let create name =
   {
     store_name = name;
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/unix32.ml ./src/utils/lib/unix32.ml
--- ./src/utils/lib/unix32.ml	2005-12-17 21:11:39.000000000 +0100
+++ ./src/utils/lib/unix32.ml	2005-12-28 19:43:38.000000000 +0100
@@ -1621,4 +1621,6 @@
       H.iter (fun _ -> incr counter) table;
       Printf.bprintf buf "  table: %d\n" !counter;
       Printf.bprintf buf "  modified_files: %d\n" (List.length !modified_files);
+      Printf.bprintf buf "  max cache_size: %d\n" !max_cache_size;
+      Printf.bprintf buf "  fd cache_size: %d\n" !FDCache.cache_size
   )
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/net/tcpBufferedSocket.ml ./src/utils/net/tcpBufferedSocket.ml
--- ./src/utils/net/tcpBufferedSocket.ml	2005-12-14 22:17:47.000000000 +0100
+++ ./src/utils/net/tcpBufferedSocket.ml	2005-12-28 19:43:38.000000000 +0100
@@ -24,7 +24,7 @@
 
 let latencies = Hashtbl.create 2131
 
-let max_opened_connections = ref (fun () -> maxi 20 (MlUnix.max_sockets - 50))
+let max_opened_connections = ref (fun () -> 20)
 let max_connections_per_second = ref (fun () -> 50)
 
 let opened_connections = ref 0
@@ -1842,6 +1842,8 @@
       Printf.bprintf buf "  read_bandwidth_controlers: %d\n" (List.length !read_bandwidth_controlers);
       Printf.bprintf buf "  write_bandwidth_controlers: %d\n" (List.length !write_bandwidth_controlers);
       Printf.bprintf buf "  to_deflate: %d\n" (List.length !to_deflate);
+      Printf.bprintf buf "  max_opened_connections: %d\n" (!max_opened_connections ());
+      Printf.bprintf buf "  max_connections_per_second: %d\n" (!max_connections_per_second ());
   );
   add_infinite_timer 1.0 proc_net_timer
 
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/net/tcpServerSocket.ml ./src/utils/net/tcpServerSocket.ml
--- ./src/utils/net/tcpServerSocket.ml	2005-12-01 00:34:29.000000000 +0100
+++ ./src/utils/net/tcpServerSocket.ml	2005-12-28 19:43:38.000000000 +0100
@@ -116,7 +116,7 @@
 	Pervasives.exit 69
       | _ -> raise e
   
-let create_connections_contoler name f =
+let create_connections_controler name f =
   let cc = {
       cc_name = name;
       nconnections_last_second = 0;
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/net/tcpServerSocket.mli ./src/utils/net/tcpServerSocket.mli
--- ./src/utils/net/tcpServerSocket.mli	2005-04-13 23:52:27.000000000 +0200
+++ ./src/utils/net/tcpServerSocket.mli	2005-12-28 19:43:38.000000000 +0100
@@ -30,5 +30,5 @@
   
 type connections_controler    
 val set_accept_controler : t -> connections_controler -> unit
-val create_connections_contoler : string -> (int -> int -> bool) -> connections_controler
+val create_connections_controler : string -> (int -> int -> bool) -> connections_controler
   
\ Kein Zeilenumbruch am Dateiende.
