summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--netcheck.c96
-rw-r--r--netcheck.h11
-rw-r--r--netmon.c89
4 files changed, 110 insertions, 88 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 67e49f9..efdf954 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,4 +4,4 @@ project(netmon C)
set(CMAKE_C_STANDARD 99)
add_compile_definitions(DEBUG)
-add_executable(netmon netmon.c logging.c logging.h)
+add_executable(netmon netmon.c logging.c logging.h netcheck.c netcheck.h)
diff --git a/netcheck.c b/netcheck.c
new file mode 100644
index 0000000..4900e0f
--- /dev/null
+++ b/netcheck.c
@@ -0,0 +1,96 @@
+//
+// Created by Keuin on 2021/12/29.
+//
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "logging.h"
+#include "netcheck.h"
+
+/**
+ * Check network availability.
+ * @return Zero if success, non-zero if failed.
+ */
+int check_network(void *logger) {
+#define RETURN(r) do { rv = (r); goto RET; } while(0)
+#define READ_SIZE 32
+
+ int sock = -1, rv = 0;
+ struct sockaddr_in serv_addr;
+ const char *msg = "GET / HTTP/1.1\r\n"
+ "Host: www.gov.cn\r\n"
+ "\r\n";
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ perror("socket()");
+ log_error(logger, "socket() failed.");
+ RETURN(-1);
+ }
+
+ const struct hostent *host = gethostbyname("www.gov.cn"); // TODO cache this
+
+ if (!host) {
+ herror("gethostbyname()");
+ log_error(logger, "Cannot resolve test host.");
+ RETURN(-1);
+ }
+
+ if (host->h_length <= 0) {
+ log_error(logger, "Test host does not have at least one address.");
+ RETURN(-1);
+ }
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_port = htons(80);
+ serv_addr.sin_addr = **((struct in_addr **) host->h_addr_list);
+
+ if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
+ log_error(logger, "connect() failed.");
+ RETURN(-1);
+ }
+
+ ssize_t ss = 0; // send size
+ while (ss < strlen(msg)) {
+ ssize_t rd = send(sock, msg, strlen(msg), 0);
+ if (rd < 0) {
+ perror("send()");
+ log_error(logger, "send() failed.");
+ RETURN(-1);
+ }
+ ss += rd;
+ }
+
+ log_debug(logger, "HTTP request is sent. Reading response.");
+ char response[READ_SIZE] = {0};
+ ssize_t rs = 0; // receive size
+ while (rs < READ_SIZE) {
+ ssize_t rd = read(sock, response, READ_SIZE - rs);
+ if (rd < 0) {
+ perror("read()");
+ log_error(logger, "read() failed.");
+ RETURN(-1);
+ } else {
+ rs += rd;
+ }
+ }
+
+ const char *expected = "HTTP/1.1 200 OK\r\n";
+ if (memcmp(response, expected, strlen(expected)) != 0) {
+ char buf[64];
+ snprintf(buf, 63, "Unexpected response: %s", response);
+ log_error(logger, buf);
+ RETURN(-1);
+ }
+ RETURN(0);
+
+ RET:
+ if (sock >= 0) close(sock);
+ return rv;
+#undef RETURN
+#undef READ_SIZE
+} \ No newline at end of file
diff --git a/netcheck.h b/netcheck.h
new file mode 100644
index 0000000..3bea521
--- /dev/null
+++ b/netcheck.h
@@ -0,0 +1,11 @@
+//
+// Created by Keuin on 2021/12/29.
+//
+
+#ifndef NETMON_NETCHECK_H
+#define NETMON_NETCHECK_H
+
+
+int check_network(void *logger);
+
+#endif //NETMON_NETCHECK_H
diff --git a/netmon.c b/netmon.c
index 2c500d9..0b0a434 100644
--- a/netmon.c
+++ b/netmon.c
@@ -1,13 +1,11 @@
#include "logging.h"
+#include "netcheck.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
const char *logfile = "netmon.log";
int check_interval_seconds = 30; // seconds to sleep between checks
@@ -88,89 +86,6 @@ void daemonize() {
// }
//}
-/**
- * Check network availability.
- * @return Zero if success, non-zero if failed.
- */
-int check_network() {
-#define RETURN(r) do { rv = (r); goto RET; } while(0)
-#define READ_SIZE 32
-
- int sock = -1, rv = 0;
- struct sockaddr_in serv_addr;
- const char *msg = "GET / HTTP/1.1\r\n"
- "Host: www.gov.cn\r\n"
- "\r\n";
-
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("socket()");
- log_error(logger, "socket() failed.");
- RETURN(-1);
- }
-
- const struct hostent *host = gethostbyname("www.gov.cn"); // TODO cache this
-
- if (!host) {
- herror("gethostbyname()");
- log_error(logger, "Cannot resolve test host.");
- RETURN(-1);
- }
-
- if (host->h_length <= 0) {
- log_error(logger, "Test host does not have at least one address.");
- RETURN(-1);
- }
-
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(80);
- serv_addr.sin_addr = **((struct in_addr **) host->h_addr_list);
-
- if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
- log_error(logger, "connect() failed.");
- RETURN(-1);
- }
-
- ssize_t ss = 0; // send size
- while (ss < strlen(msg)) {
- ssize_t rd = send(sock, msg, strlen(msg), 0);
- if (rd < 0) {
- perror("send()");
- log_error(logger, "send() failed.");
- RETURN(-1);
- }
- ss += rd;
- }
-
- log_debug(logger, "HTTP request is sent. Reading response.");
- char response[READ_SIZE] = {0};
- ssize_t rs = 0; // receive size
- while (rs < READ_SIZE) {
- ssize_t rd = read(sock, response, READ_SIZE - rs);
- if (rd < 0) {
- perror("read()");
- log_error(logger, "read() failed.");
- RETURN(-1);
- } else {
- rs += rd;
- }
- }
-
- const char *expected = "HTTP/1.1 200 OK\r\n";
- if (memcmp(response, expected, strlen(expected)) != 0) {
- char buf[64];
- snprintf(buf, 63, "Unexpected response: %s", response);
- log_error(logger, buf);
- RETURN(-1);
- }
- RETURN(0);
-
- RET:
- if (sock >= 0) close(sock);
- return rv;
-#undef RETURN
-#undef READ_SIZE
-}
-
void loop() {
// check network and sleep
// if fails too many times continuously, set require_reboot flag and return
@@ -179,7 +94,7 @@ void loop() {
#pragma ide diagnostic ignored "EndlessLoop"
while (1) {
log_info(logger, "Check network.");
- if (check_network() != 0) {
+ if (check_network(logger) != 0) {
++failures;
char buf[64];
snprintf(buf, 63, "Network failure detected. counter=%d", failures);