penguin/tinyproxy

An L4 proxy designed to act as a tiny transparent shim

commit 0352e989c99494297778f5d23855ab55be8db862

author斟酌 鵬兄 <tgckpg@gmail.com>
date2026-05-31T19:12:30Z
subjectFixed windows compat
commit 0352e989c99494297778f5d23855ab55be8db862
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2026-05-31T19:12:30Z

    Fixed windows compat
---
 src/compat.h       | 28 ++++++++++++++++++++++++++++
 src/datagram_raw.c | 27 ++++++++++++++++++++++++---
 2 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/src/compat.h b/src/compat.h
index 80b5cfd..05263b7 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -97,6 +97,34 @@ static inline uint16_t compat_raw_ip_off(uint16_t off)
 #endif
 }
 
+static inline int compat_socket_errno(void)
+{
+#ifdef _WIN32
+	int err = WSAGetLastError();
+
+	switch (err) {
+	case WSAEACCES:
+		return EACCES;
+	case WSAEINVAL:
+		return EINVAL;
+	case WSAEADDRNOTAVAIL:
+		return EADDRNOTAVAIL;
+	case WSAEMSGSIZE:
+		return EMSGSIZE;
+	case WSAENETUNREACH:
+		return ENETUNREACH;
+	case WSAEHOSTUNREACH:
+		return EHOSTUNREACH;
+	case WSAENOBUFS:
+		return ENOBUFS;
+	default:
+		return EIO;
+	}
+#else
+	return errno;
+#endif
+}
+
 #if defined(AF_INET) && \
 	defined(SOCK_RAW) && \
 	defined(IPPROTO_RAW) && \
diff --git a/src/datagram_raw.c b/src/datagram_raw.c
index 6be0353..65d23b3 100644
--- a/src/datagram_raw.c
+++ b/src/datagram_raw.c
@@ -42,13 +42,17 @@ int datagram_raw_open_ipv4(evutil_socket_t *out_fd)
 		return -EINVAL;
 	}
 
+#ifdef _WIN32
+	fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+#else
 	fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+#endif
 	if (fd < 0) {
-		return -errno;
+		return -compat_socket_errno();
 	}
 
 	if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, compat_setsockopt_optval(&one), sizeof(one)) < 0) {
-		int err = errno;
+		int err = compat_socket_errno();
 		evutil_closesocket(fd);
 		return -err;
 	}
@@ -181,7 +185,24 @@ int datagram_raw_send_udp_ipv4(
 	free(packet);
 
 	if (n < 0) {
-		return -errno;
+#ifdef _WIN32
+		LOG_ERROR("datagram raw send failed",
+				"wsaerr", _LOGV(WSAGetLastError()),
+				"packet_len", _LOGV(packet_len),
+				"src_ip", _LOGV(src_addr.sin_addr.s_addr),
+				"src_port", _LOGV(ntohs(src_addr.sin_port)),
+				"dst_ip", _LOGV(dst->sin_addr.s_addr),
+				"dst_port", _LOGV(ntohs(dst->sin_port))
+				);
+#else
+		LOG_ERROR("datagram raw send failed",
+				"err", _LOGV(strerror(errno)),
+				"packet_len", _LOGV(packet_len),
+				"src_port", _LOGV(ntohs(src_addr.sin_port)),
+				"dst_port", _LOGV(ntohs(dst->sin_port))
+				);
+#endif
+		return -compat_socket_errno();
 	}
 
 	if ((size_t)n != packet_len) {