Quellcode durchsuchen

Fix to do TCP port number randomization at boot.

This addresses the issue where a server would otherwise reject a valid
connection attempt from a rebooted node, due to the server thinking that
packet belonged to a recently closed session. By starting off the local
TCP port numbers at random* points each boot the risk of port reuse
across a reboot is significantly reduced.

*) As random as can be had via the lower 12 bits of the ccounter.
Johny Mattsson vor 8 Jahren
Ursprung
Commit
f82415f6b9
3 geänderte Dateien mit 28 neuen und 1 gelöschten Zeilen
  1. 1 1
      app/lwip/core/tcp.c
  2. 18 0
      app/user/user_main.c
  3. 9 0
      ld/nodemcu.ld

+ 1 - 1
app/lwip/core/tcp.c

@@ -635,7 +635,7 @@ tcp_new_port(void)
 #define TCP_LOCAL_PORT_RANGE_START 4096
 #define TCP_LOCAL_PORT_RANGE_END   0x7fff
 #endif
-  static u16_t port = TCP_LOCAL_PORT_RANGE_START;
+  static u16_t port __attribute__((section(".port"))) = TCP_LOCAL_PORT_RANGE_START;
   
  again:
   if (++port >= TCP_LOCAL_PORT_RANGE_END) {

+ 18 - 0
app/user/user_main.c

@@ -51,6 +51,21 @@ void TEXT_SECTION_ATTR user_start_trampoline (void)
 }
 
 
+/* To avoid accidentally losing the fix for the TCP port randomization
+ * during an LWIP upgrade, we've implemented most it outside the LWIP
+ * source itself. This enables us to test for the presence of the fix
+ * /at link time/ and error out if it's been lost.
+ * The fix itself consists of putting the function-static 'port' variable
+ * into its own section, and get the linker to provide an alias for it.
+ * From there we can then manually randomize it at boot.
+ */
+static inline void tcp_random_port_init (void)
+{
+  extern uint16_t _tcp_new_port_port; // provided by the linker script
+  _tcp_new_port_port += xthal_get_ccount () % 4096;
+}
+
+
 void task_lua(os_event_t *e){
     char* lua_argv[] = { (char *)"lua", (char *)"-i", NULL };
     NODE_DBG("Task task_lua started.\n");
@@ -145,6 +160,9 @@ void nodemcu_init(void)
     // char* lua_argv[] = { (char *)"lua", (char *)"-e", (char *)"pwm.setup(0,100,50) pwm.start(0) pwm.stop(0)", NULL };
     // lua_main( 3, lua_argv );
     // NODE_DBG("Flash sec num: 0x%x\n", flash_get_sec_num());
+
+    tcp_random_port_init ();
+
     task_init();
     system_os_post(LUA_TASK_PRIO,SIG_LUA,'s');
 }

+ 9 - 0
ld/nodemcu.ld

@@ -113,6 +113,15 @@ SECTIONS
   {
     _data_start = ABSOLUTE(.);
     *(.data)
+
+    /* Hook for randomizing TCP start numbers */
+    _tcp_new_port_port = ABSOLUTE(.);
+    */liblwip.a:tcp.o(.port)
+    /* Verify that the LWIP source has been patched as needed, or fail with
+     * a divide by zero error (../ld/nodemcu.ld:xxx / by zero) */
+    _tcp_new_port_port_size = ABSOLUTE(.) - _tcp_new_port_port;
+    _ensure_tcp_port_randomization_fix_presence = 1 / _tcp_new_port_port_size;
+
     *(.data.*)
     *(.gnu.linkonce.d.*)
     *(.data1)