In processPacket() always check the response of queuePacket(), to
authorDavin McCall <davmac@davmac.org>
Sun, 22 Nov 2015 14:50:13 +0000 (14:50 +0000)
committerDavin McCall <davmac@davmac.org>
Sun, 22 Nov 2015 14:50:13 +0000 (14:50 +0000)
avoid writing to instance variables after the ControlConn instance
has been deleted.

Also make some functions private.

control.cc
control.h

index a73b848555427f7619ebd0f5e3f43e098be0a337..7cf55725773f5331d0d06f8d0282d674513fe065 100644 (file)
@@ -18,7 +18,7 @@ void ControlConn::processPacket()
         if (svcSize <= 0) {
             // Queue error response mark connection bad
             char badreqRep[] = { DINIT_RP_BADREQ };
-            queuePacket(badreqRep, 1);
+            if (! queuePacket(badreqRep, 1)) return;
             bad_conn_close = true;
             ev_io_set(&iob, iob.fd, EV_WRITE);
             return;
@@ -44,15 +44,15 @@ void ControlConn::processPacket()
             try {
                 char ack_buf[] = { DINIT_RP_ACK };
                 service_set->startService(serviceName.c_str());
-                queuePacket(ack_buf, 1);
+                if (! queuePacket(ack_buf, 1)) return;
             }
             catch (ServiceLoadExc &slexc) {
                 char outbuf[] = { DINIT_RP_SERVICELOADERR };
-                queuePacket(outbuf, 1);
+                if (! queuePacket(outbuf, 1)) return;
             }
             catch (std::bad_alloc &baexc) {
                 char outbuf[] = { DINIT_RP_SERVICEOOM };
-                queuePacket(outbuf, 1); // might degenerate to DINIT_RP_OOM, which is fine.
+                if (! queuePacket(outbuf, 1)) return; // might degenerate to DINIT_RP_OOM, which is fine.
             }
         }
         else {
@@ -72,7 +72,7 @@ void ControlConn::processPacket()
             service_set->stop_all_services();
             log_to_console = true;
             char ackBuf[] = { DINIT_RP_ACK };
-            queuePacket(ackBuf, 1);
+            if (! queuePacket(ackBuf, 1)) return;
         }
         else {
             // TODO send NAK
@@ -195,10 +195,10 @@ bool ControlConn::queuePacket(std::vector<char> &&pkt) noexcept
     }
 }
 
-void ControlConn::rollbackComplete() noexcept
+bool ControlConn::rollbackComplete() noexcept
 {
     char ackBuf[1] = { DINIT_ROLLBACK_COMPLETED };
-    queuePacket(ackBuf, 1);
+    return queuePacket(ackBuf, 1);
 }
 
 void ControlConn::dataReady() noexcept
index 779ce29ecf2fef6028c700e1227af53b3760bbf8..79126a1242fa4e6c3b00d33783134168e808e197 100644 (file)
--- a/control.h
+++ b/control.h
@@ -34,6 +34,8 @@ class ServiceSet;
 
 class ControlConn
 {
+    friend void control_conn_cb(struct ev_loop *, ev_io *, int);
+    
     struct ev_io iob;
     struct ev_loop *loop;
     ServiceSet *service_set;
@@ -64,6 +66,10 @@ class ControlConn
     // Process a packet. Can cause the ControlConn to be deleted iff there are no
     // outgoing packets queued.
     void processPacket();
+
+    // Notify that data is ready to be read from the socket.
+    void dataReady() noexcept;
+    void sendData() noexcept;
     
     public:
     ControlConn(struct ev_loop * loop, ServiceSet * service_set, int fd) : loop(loop), service_set(service_set), bufidx(0), chklen(0)
@@ -77,12 +83,8 @@ class ControlConn
         active_control_conns++;
     }
     
-    void rollbackComplete() noexcept;
-    // Notify that data is ready to be read from the socket.
-    void dataReady() noexcept;
-    void sendData() noexcept;
-    
-    
+    bool rollbackComplete() noexcept;
+        
     ~ControlConn() noexcept;
 };