| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2016-05-27 13:27:44 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2016-05-27 13:27:44 +0200 | 
| commit | ecdebd8f416b803b43ce93533666599e1442f62d (patch) | |
| tree | b6afeb478402efbfbba01247808da7ff70f8ae01 /src/io/network.c | |
| parent | 23abb2acd221762ec482985f91fa3eff1123fb9a (diff) | |
Working on improving the network handling.
Diffstat (limited to 'src/io/network.c')
| -rw-r--r-- | src/io/network.c | 417 | 
1 files changed, 213 insertions, 204 deletions
| diff --git a/src/io/network.c b/src/io/network.c index c8d05a2..d2797c9 100644 --- a/src/io/network.c +++ b/src/io/network.c @@ -13,10 +13,10 @@  #include "network.h" -static int reconnect (struct ZoO_network net [const restrict static 1]) +static int re_create_socket (struct ZoO_network net [const restrict static 1])  {     struct timeval timeout; -   int old_errno = errno; +   const int old_errno = errno;     errno = 0;     timeout.tv_sec = ZoO_NETWORK_TIMEOUT; @@ -37,19 +37,11 @@ static int reconnect (struct ZoO_network net [const restrict static 1])     if (net->connection == -1)     { -      ZoO_FATAL -      ( -         "Could not create socket: %s.", -         strerror(errno) -      ); +      ZoO_ERROR("Could not create socket: %s.", strerror(errno)); -      errno = old_errno; - -      return -1; +      goto RETURN_FAILED;     } -   errno = 0; -     if     (        ( @@ -77,13 +69,9 @@ static int reconnect (struct ZoO_network net [const restrict static 1])     {        ZoO_ERROR("Could not set timeout on network socket: %s", strerror(errno)); -      errno = old_errno; - -      return -1; +      goto RETURN_FAILED;     } -   errno = old_errno; -     ZoO_S_DEBUG(ZoO_DEBUG_NETWORK, "(Re)connecting to network...");     if @@ -96,73 +84,67 @@ static int reconnect (struct ZoO_network net [const restrict static 1])        ) != 0     )     { -      ZoO_ERROR -      ( -         "Unable to connect to the network: %s", -         strerror(errno) -      ); +      ZoO_ERROR("Could not establish connection: %s", strerror(errno)); -      errno = old_errno; - -      return -1; +      goto RETURN_FAILED;     }     errno = old_errno; -   snprintf -   ( -      net->msg, -      512, -      "USER %s 8 * :%s\r\n", -      net->user, -      net->name -   ); +   return 0; -   errno = 0; +RETURN_FAILED: +   errno = old_errno; -   if (write(net->connection, net->msg, strlen(net->msg)) < 1) -   { -      ZoO_ERROR -      ( -         "Unable to write to the network: %s", -         strerror(errno) -      ); +   return -1; +} -      errno = old_errno; +static int reconnect (struct ZoO_network net [const restrict static 1]) +{ +   const int old_errno = errno; +   memset(net->in, 0, (sizeof(ZoO_char) * 513)); +   memset(net->out, 0, (sizeof(ZoO_char) * 513)); +   memset(net->buffer, 0, (sizeof(ZoO_char) * 513)); + +   if (re_create_socket(net) < 0) +   {        return -1;     } -   snprintf -   ( -      net->msg, -      512, -      "NICK %s\r\n", -      net->nick -   ); - -   errno = 0; +   snprintf(net->out, 512, "USER %s 8 * :%s\r\n", net->user, net->name); -   if (write(net->connection, net->msg, strlen(net->msg)) < 1) +   if (write(net->connection, net->out, strlen(net->out)) < 1)     { -      ZoO_ERROR -      ( -         "Unable to write to the network: %s", -         strerror(errno) -      ); +      goto RETURN_WRITE_FAILED; +   } -      errno = old_errno; +   snprintf(net->out, 512, "NICK %s\r\n", net->nick); -      return -1; +   if (write(net->connection, net->out, strlen(net->out)) < 1) +   { +      goto RETURN_WRITE_FAILED;     } -   errno = old_errno; -     net->buffer_remaining = 0;     net->buffer_index = 0; +     ZoO_S_DEBUG(ZoO_DEBUG_NETWORK, "(Re)connected."); +   errno = old_errno; +     return 0; + +RETURN_WRITE_FAILED: +   ZoO_ERROR +   ( +      "Unable to write to the network: %s", +      strerror(errno) +   ); + +   errno = old_errno; + +   return -1;  }  int ZoO_network_connect @@ -189,7 +171,9 @@ int ZoO_network_connect     net->buffer_remaining = 0;     memset(&hints, 0, sizeof(struct addrinfo)); -   memset(net->msg, 0, (sizeof(ZoO_char) * 513)); +   memset(net->in, 0, (sizeof(ZoO_char) * 513)); +   memset(net->out, 0, (sizeof(ZoO_char) * 513)); +   memset(net->buffer, 0, (sizeof(ZoO_char) * 513));     hints.ai_family = AF_INET;     hints.ai_socktype = SOCK_STREAM; @@ -222,215 +206,240 @@ int ZoO_network_connect        return -1;     } -   errno = 0; - +   errno = old_errno;     reconnect(net);     return 0;  } -int ZoO_network_receive +static void buffer_msg  ( -   struct ZoO_network net [const restrict static 1], -   size_t msg_offset [const restrict static 1], -   size_t msg_size [const restrict static 1] +   struct ZoO_network net [const static 1]  )  { -   int old_errno; -   ssize_t in_count, in_index, msg_index, cmd; +   ssize_t in_count, i; -   old_errno = errno; +   if (net->buffer_remaining > 0) +   { +      in_count = net->buffer_remaining; +      net->buffer_remaining = 0; + +      goto PARSE_READ; +   } -   for (;;) +READ_MORE: +   in_count = read(net->connection, net->buffer, 512); + +   if (in_count < 0)     { -      msg_index = 0; +      ZoO_ERROR("Could not read from network: %s", strerror(errno)); + +      reconnect(net); -      errno = 0; +      goto READ_MORE; +   } + +PARSE_READ: +   for (i = 0; i < in_count; ++i) +   { +      net->in[net->buffer_index] = net->buffer[i]; -      while +      if        ( -         ( -            (in_count = -               read( -                  net->connection, -                  (net->buffer + net->buffer_index), -                  (512 - net->buffer_index) -               ) -            ) > 0 -         ) +         (net->buffer_index > 0) +         && (net->in[net->buffer_index - 1] == '\r') +         && (net->in[net->buffer_index] == '\n')        )        { -         net->buffer_remaining += in_count; +         net->buffer_remaining = (in_count - (i + 1)); +         net->in_length = (net->buffer_index - 1); +         net->buffer_index = 0; -         for -         ( -            in_index = 0; -            in_index < net->buffer_remaining; -            ++in_index -         ) +         if (net->buffer_remaining > 0)           { -            net->msg[msg_index] = net->buffer[net->buffer_index + in_index]; - -            if +            memmove              ( -               (msg_index == 511) -               || -               ( -                  (msg_index > 0) -                  && (net->msg[msg_index - 1] == '\r') -                  && (net->msg[msg_index] == '\n') -               ) -            ) -            { -               net->msg[msg_index + 1] = '\0'; +               (void *) net->buffer, +               (const void *) (net->buffer + (i + 1)), +               net->buffer_remaining +            ); +         } +         return; +      } -               if (net->buffer_index != net->buffer_remaining) -               { -                  memmove -                  ( -                     net->buffer, -                     (net->buffer + net->buffer_index), -                     (size_t) net->buffer_remaining -                  ); +      net->buffer_index += 1; -                  net->buffer_index = 0; -               } +      if (net->buffer_index > 512) +      { +         ZoO_S_WARNING("Incoming message is too long. Discarded."); -               net->buffer_remaining -= (in_index + 1); +         net->buffer_index = 0; +         net->buffer_remaining = 0; -               errno = old_errno; +         break; +      } +   } -               goto READ_MSG; -            } +   goto READ_MORE; +} -            ++msg_index; -         } +void handle_ping (struct ZoO_network net [const restrict static 1]) +{ +   const int old_errno = errno; -         net->buffer_remaining = 0; -         net->buffer_index = 0; +   #if ZoO_DEBUG_NETWORK_PING == 1 +      net->in[net->in_length] = '\0'; -         errno = 0; -      } +      ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->in] %s", net->in); -      ZoO_ERROR -      ( -         "Something went wrong while trying to read from the network: %s.", -         strerror(errno) -      ); +      net->in[net->in_length] = '\r'; +   #endif + +   net->in[1] = 'O'; + +   errno = 0; + +   if (write(net->connection, net->in, (net->in_length + 2)) < 1) +   { +      ZoO_ERROR("Could not reply to PING request: %s", strerror(errno));        errno = old_errno; -      if (reconnect(net) < 0) +      while (reconnect(net) < 0)        { -         return -1; +         sleep(5);        } -      continue; +      return; +   } -      READ_MSG: +   errno = old_errno; -      ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->in] %s\n", net->msg); +#if ZoO_DEBUG_NETWORK_PING == 1 +   net->in[net->in_length] = '\0'; -      /* XXX: doesn't that prevent net [restrict]? */ -      if (ZoO_IS_PREFIX("PING", net->msg)) -      { -         errno = 0; +   ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->in); +#endif -         net->msg[1] = 'O'; +} -         if (write(net->connection, net->msg, strlen(net->msg)) < 1) -         { -            ZoO_ERROR("Could not reply to PING request: %s", strerror(errno)); +int ZoO_network_receive +( +   struct ZoO_network net [const restrict static 1], +   size_t msg_offset [const restrict static 1], +   size_t msg_size [const restrict static 1], +   enum ZoO_msg_type type [const restrict static 1] +) +{ +   const int old_errno = errno; +   ssize_t cmd, i; -            errno = old_errno; +READ_NEW_MSG: +   buffer_msg(net); -            if (reconnect(net) < 0) -            { -               return -1; -            } +   net->in[net->in_length + 2] = '\0'; -            continue; -         } +   /* XXX: doesn't that prevent net [restrict]? */ +   if (ZoO_IS_PREFIX("PING", net->in)) +   { -         ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s\n", net->msg); +      handle_ping(net); -         errno = old_errno; -      } -      else if (net->msg[0] == ':') -      { -         cmd = 0; +      goto READ_NEW_MSG; +   } -         for (in_index = 1; in_index < 512; in_index++) -         { -            if (net->msg[in_index] == ' ') -            { -               cmd = (in_index + 1); +   if (net->in_length == 0) +   { +      goto READ_NEW_MSG; +   } -               break; -            } -         } +   net->in[net->in_length] = '\0'; + +   ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->in] %s", net->in); + +   if (net->in[0] == ':') +   { +      cmd = 0; -         if (cmd == 0) +      for (i = 1; i < 512; i++) +      { +         if (net->in[i] == ' ')           { -            continue; +            cmd = (i + 1); + +            break;           } +      } + +      if (ZoO_IS_PREFIX("001", (net->in + cmd))) +      { +         snprintf +         ( +            net->out, +            512, +            "JOIN :%s\r\n", +            net->channel +         ); -         if (ZoO_IS_PREFIX("001", (net->msg + cmd))) +         errno = 0; + +         if (write(net->connection, net->out, strlen(net->out)) < 1)           { -            snprintf +            ZoO_ERROR              ( -               net->msg, -               512, -               "JOIN :%s\r\n", -               net->channel +               "Could not send JOIN request: %s", +               strerror(errno)              ); -            errno = 0; +            errno = old_errno; -            if (write(net->connection, net->msg, strlen(net->msg)) < 1) +            if (reconnect(net) < 0)              { -               ZoO_ERROR -               ( -                  "Could not send JOIN request: %s", -                  strerror(errno) -               ); - -               errno = old_errno; - -               if (reconnect(net) < 0) -               { -                  return -1; -               } +               return -1;              } +         } -            ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->msg); +         errno = old_errno; -            continue; -         } +         ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->out); -         if (ZoO_IS_PREFIX("PRIVMSG", (net->msg + cmd))) +         goto READ_NEW_MSG; +      } + +      if (ZoO_IS_PREFIX("JOIN", (net->in + cmd))) +      { +         *type = ZoO_JOIN; + +         return 0; +      } + +      if (ZoO_IS_PREFIX("PRIVMSG", (net->in + cmd))) +      { + +         for (; i < 512; i++)           { -            for (; in_index < 512; in_index++) +            if (net->in[i] == ':')              { -               if (net->msg[in_index] == ':') -               { -                  cmd = (in_index + 1); +               cmd = (i + 1); -                  break; -               } +               break;              } +         } -            *msg_offset = cmd; -            *msg_size = (msg_index - *msg_offset - 1); +         *msg_offset = cmd; +         *msg_size = (net->in_length - cmd); -            /*net->msg[*msg_size - 1] = '\0'; */ +         /*net->in[*msg_size - 1] = '\0'; */ -            return 0; -         } +         *type = ZoO_PRIVMSG; + +         return 0;        }     } + +   goto READ_NEW_MSG;  }  int ZoO_network_send (struct ZoO_network net [const restrict static 1]) @@ -439,16 +448,16 @@ int ZoO_network_send (struct ZoO_network net [const restrict static 1])     snprintf     ( -      net->buffer, +      net->in,        512,        "PRIVMSG %s :%s\r\n",        net->channel, -      net->msg +      net->out     );     errno = 0; -   if (write(net->connection, net->buffer, strlen(net->buffer)) < 1) +   if (write(net->connection, net->in, strlen(net->in)) < 1)     {        ZoO_ERROR        ( @@ -470,7 +479,7 @@ int ZoO_network_send (struct ZoO_network net [const restrict static 1])     errno = old_errno; -   ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->buffer); +   ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->in);     return 0;  } | 


