--- /dev/null
+#include "log.h"
+#include "markpool.h"
+#include "udpstream.h"
+#include "util.h"
+
+UDPStream::UDPStream(const sockaddr_in6 &dst, MarkPool *mark_pool)
+ : dst(dst),
+ mark_pool(mark_pool),
+ fwmark(0)
+{
+ sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock == -1) {
+ // Oops. Ignore this output, then.
+ log_perror("socket");
+ return;
+ }
+
+ if (mark_pool != NULL) {
+ fwmark = mark_pool->get_mark();
+ if (setsockopt(sock, SOL_SOCKET, SO_MARK, &fwmark, sizeof(fwmark)) == -1) {
+ if (fwmark != 0) {
+ log_perror("setsockopt(SO_MARK)");
+ }
+ }
+ }
+}
+
+UDPStream::~UDPStream()
+{
+ if (sock != -1) {
+ safe_close(sock);
+ }
+ if (mark_pool != NULL) {
+ mark_pool->release_mark(fwmark);
+ }
+}
+
+void UDPStream::send(const char *data, size_t bytes)
+{
+ if (sock == -1) {
+ return;
+ }
+ ssize_t err = sendto(sock, data, bytes, 0, reinterpret_cast<sockaddr *>(&dst), sizeof(dst));
+ if (err == -1) {
+ log_perror("sendto");
+ }
+}