Switch from SCTP to TCP
[public/pyceo-broken.git] / src / net.c
index d5db0ad..a238f1f 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -31,139 +31,65 @@ void free_fqdn(void) {
     strbuf_release(&fqdn);
 }
 
-static size_t recv_one_message(int sock, struct sctp_meta *msg_meta, struct strbuf *msg, int *notification) {
-    size_t len = 0;
-    int flags = 0;
-    int bytes;
+int ceo_send_message(int sock, void *buf, size_t len, uint32_t msgtype) {
+    uint32_t msgheader[2];
+    msgheader[0] = htonl(len);
+    msgheader[1] = htonl(msgtype);
 
-    strbuf_reset(msg);
+    if (full_write(sock, msgheader, sizeof(msgheader)) < 0)
+        fatalpe("write");
+
+    if (full_write(sock, buf, len) < 0)
+        fatalpe("write");
 
-    do {
-        msg_meta->fromlen = sizeof(msg_meta->from);
+    return 0;
+}
 
-        bytes = sctp_recvmsg(sock, msg->buf + len, strbuf_avail(msg) - len,
-                             (sa *)&msg_meta->from, &msg_meta->fromlen, &msg_meta->sinfo, &flags);
+int ceo_receive_message(int sock, struct strbuf *msg, uint32_t *msgtype) {
+    uint32_t msglen, received = 0;
+    uint32_t msgheader[2];
+    ssize_t bytes;
 
+    strbuf_reset(msg);
+
+    while (received < sizeof(msgheader)) {
+        bytes = read(sock, msgheader, sizeof(msgheader) - received);
         if (bytes < 0) {
             if (errno == EAGAIN)
                 continue;
-            fatalpe("sctp_recvmsg");
+            fatalpe("read");
         }
+        if (!bytes && !received)
+            return -1;
         if (!bytes)
-            break;
-        len += bytes;
-
-        if (msg->len > MAX_MSGLEN)
-            fatal("oversized message received");
-        if (strbuf_avail(msg) < MSG_BUFINC)
-            strbuf_grow(msg, MSG_BUFINC);
-
-    } while (~flags & MSG_EOR);
-
-    if (!bytes && len)
-        fatalpe("EOF in the middle of a message");
-
-    *notification = flags & MSG_NOTIFICATION;
-    if (*notification) {
-        notification_dbg(msg->buf);
-        union sctp_notification *sn = (union sctp_notification *) msg->buf;
-        switch (sn->sn_header.sn_type) {
-            case SCTP_SHUTDOWN_EVENT:
-                fatal("connection shut down");
-                break;
-            case SCTP_ASSOC_CHANGE:
-                switch (sn->sn_assoc_change.sac_state) {
-                    case SCTP_COMM_LOST:
-                        fatal("connection lost");
-                        break;
-                    case SCTP_SHUTDOWN_COMP:
-                        fatal("shutdown complete");
-                        break;
-                    case SCTP_CANT_STR_ASSOC:
-                        fatal("connection failed (is ceod running?)");
-                        break;
-                }
-                break;
-        }
+            fatalpe("short header received");
+        received += bytes;
     }
 
-    strbuf_setlen(msg, len);
-    return len;
-}
+    msglen = ntohl(msgheader[0]);
+    *msgtype = ntohl(msgheader[1]);
+    received = 0;
 
-int receive_one_message(int sock, struct sctp_meta *msg_meta, struct strbuf *msg) {
-    int notification = 0;
+    if (!msglen)
+        fatal("length is zero in message header");
 
-    do {
-        recv_one_message(sock, msg_meta, msg, &notification);
-    } while (notification);
+    if (msglen > MAX_MSGLEN)
+        fatal("length is huge in message header");
 
-    return msg->len > 0;
-}
+    strbuf_grow(msg, msglen);
+    strbuf_setlen(msg, msglen);
 
-void notification_dbg(char *notification) {
-    union sctp_notification *sn = (union sctp_notification *) notification;
-    char *extra;
-
-    switch (sn->sn_header.sn_type) {
-        case SCTP_ASSOC_CHANGE:
-            extra = "unknown state";
-            switch (sn->sn_assoc_change.sac_state) {
-                case SCTP_COMM_UP: extra = "established"; break;
-                case SCTP_COMM_LOST: extra = "lost"; break;
-                case SCTP_RESTART: extra = "restarted"; break;
-                case SCTP_SHUTDOWN_COMP: extra = "completed shutdown"; break;
-                case SCTP_CANT_STR_ASSOC: extra = "cannot start"; break;
-            }
-            debug("association changed: association 0x%x %s", sn->sn_assoc_change.sac_assoc_id, extra);
-            break;
-        case SCTP_PEER_ADDR_CHANGE:
-            extra = "unknown state";
-            switch (sn->sn_paddr_change.spc_state) {
-                case SCTP_ADDR_AVAILABLE: extra = "unavailable"; break;
-                case SCTP_ADDR_UNREACHABLE: extra = "unreachable"; break;
-                case SCTP_ADDR_REMOVED: extra = "removed"; break;
-                case SCTP_ADDR_ADDED: extra = "added"; break;
-                case SCTP_ADDR_MADE_PRIM: extra = "made primary"; break;
-#ifdef SCTP_ADDR_CONFIRMED
-                case SCTP_ADDR_CONFIRMED: extra = "confirmed"; break;
-#endif
-            }
-
-            struct sockaddr_in *sa = (struct sockaddr_in *) &sn->sn_paddr_change.spc_aaddr;
-            char addr[INET_ADDRSTRLEN];
-            inet_ntop(AF_INET, &sa->sin_addr, addr, sizeof(addr));
-            debug("peer address change: remote address %s %s", addr, extra);
-            break;
-        case SCTP_REMOTE_ERROR:
-            debug("remote error: association=0x%x error=0x%x",
-                    sn->sn_remote_error.sre_assoc_id,
-                    sn->sn_remote_error.sre_error);
-            break;
-        case SCTP_SEND_FAILED:
-            debug("send failed: association=0x%x error=0x%x",
-                    sn->sn_send_failed.ssf_assoc_id,
-                    sn->sn_send_failed.ssf_error);
-            break;
-        case SCTP_ADAPTATION_INDICATION:
-            debug("adaptation indication: 0x%x",
-                    sn->sn_adaptation_event.sai_adaptation_ind);
-            break;
-        case SCTP_PARTIAL_DELIVERY_EVENT:
-            extra = "unknown indication";
-            switch (sn->sn_pdapi_event.pdapi_indication) {
-                case SCTP_PARTIAL_DELIVERY_ABORTED:
-                    extra = "partial delivery aborted";
-                    break;
-            }
-            debug("partial delivery event: %s", extra);
-            break;
-        case SCTP_SHUTDOWN_EVENT:
-            debug("association 0x%x was shut down",
-                    sn->sn_shutdown_event.sse_assoc_id);
-            break;
-        default:
-            debug("unknown sctp notification type 0x%x\n",
-                    sn->sn_header.sn_type);
+    while (received < msglen) {
+        bytes = read(sock, msg->buf + received, msglen - received);
+        if (bytes < 0) {
+            if (errno == EAGAIN)
+                continue;
+            fatalpe("read");
+        }
+        if (!bytes)
+            fatal("short message received");
+        received += bytes;
     }
+
+    return 0;
 }