diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a221c5f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+build/
+docs/
+hermesrc.example
diff --git a/src/Proxy.h b/src/Proxy.h
index fd55da2..689aebf 100644
--- a/src/Proxy.h
+++ b/src/Proxy.h
@@ -1,61 +1,14 @@
-/**
- * hermes antispam proxy
- * Copyright (C) 2006, 2007 Juan José Gutiérrez de Quevedo <juanjo@gutierrezdequevedo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * @author Juan José Gutiérrez de Quevedo <juanjo@gutierrezdequevedo.com>
- */
-#ifndef PROXY_H
-#define PROXY_H
+// Proxy.h
+#pragma once
+#include <string>
+#include "SocketInterface.h"
 
-#include "hermes.h"
-#include <sys/param.h>
-#ifdef WIN32
-  #include <winsock2.h>
-#else
-  #include <sys/select.h>
-#endif
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <iostream>
+class Proxy {
+public:
+    Proxy(SocketInterface* outside_socket) : outside(outside_socket) {}
+    
+    void run(std::string& peer_address);
 
-#include "Socket.h"
-#include "Configfile.h"
-#include "Utils.h"
-#include "Logger.h"
-#ifdef HAVE_SPF
-#include "Spf.h"
-#endif //HAVE_SPF
-
-#define SMTP_STATE_WAIT_FOR_HELO 0
-#define SMTP_STATE_WAIT_FOR_MAILFROM 1
-#define SMTP_STATE_WAIT_FOR_RCPTTO 2
-#define SMTP_STATE_WAIT_FOR_DATA 3
-
-class Proxy
-{
-  private:
-    Socket outside; //connection from someone sending mail
-    Socket inside; //connection to our inside smtp
-  public:
-    //Proxy():outside(NULL),inside(NULL){};
-    void setOutside(Socket&);
-    void run(string&);
+private:
+    SocketInterface* outside;
 };
-
-#endif //PROXY_H
diff --git a/src/SocketInterface.cpp b/src/SocketInterface.cpp
new file mode 100644
index 0000000..0eec521
--- /dev/null
+++ b/src/SocketInterface.cpp
@@ -0,0 +1,51 @@
+// BoostSocket.h
+#include <boost/asio.hpp>
+#include "SocketInterface.h"
+
+class BoostSocket : public SocketInterface {
+public:
+    BoostSocket() : socket_(io_service_) {}
+
+    void connect(const std::string& host, unsigned short port) override {
+        boost::asio::ip::tcp::resolver resolver(io_service_);
+        boost::asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(host, std::to_string(port));
+        boost::asio::connect(socket_, endpoints);
+    }
+
+    void writeLine(const std::string& data) override {
+        boost::asio::write(socket_, boost::asio::buffer(data + "\r\n"));
+    }
+
+    std::string readLine() override {
+        boost::asio::streambuf buf;
+        boost::asio::read_until(socket_, buf, "\r\n");
+        std::istream is(&buf);
+        std::string line;
+        std::getline(is, line);
+        return line;
+    }
+
+    bool canRead(double timeout) override {
+        // Implementation to check if data is available to read.
+    }
+
+    bool isClosed() override {
+        return !socket_.is_open();
+    }
+
+    void close() override {
+        socket_.close();
+    }
+
+    void prepareSSL(bool incoming) override {
+        // Implement SSL preparation here if needed.
+    }
+
+    void startSSL(bool incoming) override {
+        // Implement starting SSL here if needed.
+    }
+
+private:
+    boost::asio::io_service io_service_;
+    boost::asio::ip::tcp::socket socket_;
+};
diff --git a/src/SocketInterface.h b/src/SocketInterface.h
new file mode 100644
index 0000000..bce1566
--- /dev/null
+++ b/src/SocketInterface.h
@@ -0,0 +1,16 @@
+// SocketInterface.h
+#pragma once
+#include <string>
+
+class SocketInterface {
+public:
+    virtual ~SocketInterface() = default;
+    virtual void connect(const std::string& host, unsigned short port) = 0;
+    virtual void writeLine(const std::string& data) = 0;
+    virtual std::string readLine() = 0;
+    virtual bool canRead(double timeout) = 0;
+    virtual bool isClosed() = 0;
+    virtual void close() = 0;
+    virtual void prepareSSL(bool incoming) = 0;
+    virtual void startSSL(bool incoming) = 0;
+};
diff --git a/src/test/MockSocket.h b/src/test/MockSocket.h
new file mode 100644
index 0000000..63e3819
--- /dev/null
+++ b/src/test/MockSocket.h
@@ -0,0 +1,15 @@
+// MockSocket.h
+#include "SocketInterface.h"
+#include <gmock/gmock.h>
+
+class MockSocket : public SocketInterface {
+public:
+    MOCK_METHOD(void, connect, (const std::string& host, unsigned short port), (override));
+    MOCK_METHOD(void, writeLine, (const std::string& data), (override));
+    MOCK_METHOD(std::string, readLine, (), (override));
+    MOCK_METHOD(bool, canRead, (double timeout), (override));
+    MOCK_METHOD(bool, isClosed, (), (override));
+    MOCK_METHOD(void, close, (), (override));
+    MOCK_METHOD(void, prepareSSL, (bool incoming), (override));
+    MOCK_METHOD(void, startSSL, (bool incoming), (override));
+};
diff --git a/src/test/ProxyTest.cpp b/src/test/ProxyTest.cpp
new file mode 100644
index 0000000..c8e0412
--- /dev/null
+++ b/src/test/ProxyTest.cpp
@@ -0,0 +1,63 @@
+// ProxyTest.cpp
+#include <gtest/gtest.h>
+#include "Proxy.h"
+#include "MockSocket.h"
+
+class ProxyTest : public ::testing::Test {
+protected:
+    MockSocket mock_socket;
+    Proxy* proxy;
+
+    void SetUp() override {
+        proxy = new Proxy(&mock_socket);
+    }
+
+    void TearDown() override {
+        delete proxy;
+    }
+};
+
+TEST_F(ProxyTest, HandlesMailFromCommand) {
+    std::string peer_address = "127.0.0.1";
+
+    EXPECT_CALL(mock_socket, connect("server-host", 25));
+    EXPECT_CALL(mock_socket, canRead(0.2)).WillOnce(testing::Return(true));
+    EXPECT_CALL(mock_socket, readLine()).WillOnce(testing::Return("MAIL FROM:<test@example.com>"));
+    EXPECT_CALL(mock_socket, writeLine("MAIL FROM:<test@example.com>"));
+    EXPECT_CALL(mock_socket, writeLine("250 OK"));
+
+    proxy->run(peer_address);
+}
+
+TEST_F(ProxyTest, HandlesRcptToCommand) {
+    std::string peer_address = "127.0.0.1";
+
+    EXPECT_CALL(mock_socket, connect("server-host", 25));
+    EXPECT_CALL(mock_socket, canRead(0.2)).WillRepeatedly(testing::Return(true));
+    EXPECT_CALL(mock_socket, readLine())
+        .WillOnce(testing::Return("MAIL FROM:<test@example.com>"))
+        .WillOnce(testing::Return("RCPT TO:<receiver@example.com>"))
+        .WillOnce(testing::Return(""));
+
+    EXPECT_CALL(mock_socket, writeLine("MAIL FROM:<test@example.com>"));
+    EXPECT_CALL(mock_socket, writeLine("RCPT TO:<receiver@example.com>"));
+    EXPECT_CALL(mock_socket, writeLine("250 OK"));
+
+    proxy->run(peer_address);
+}
+
+TEST_F(ProxyTest, HandlesEmptyLine) {
+    std::string peer_address = "127.0.0.1";
+
+    EXPECT_CALL(mock_socket, connect("server-host", 25));
+    EXPECT_CALL(mock_socket, canRead(0.2)).WillOnce(testing::Return(true));
+    EXPECT_CALL(mock_socket, readLine()).WillOnce(testing::Return(""));
+
+    proxy->run(peer_address);
+    // Expect no further actions to occur
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleMock(&argc, argv);
+    return RUN_ALL_TESTS();
+}
\ No newline at end of file