0

Edit: realized I need an implementation of this on C#: https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT

I'll try to find one, if anyone has one I'll appreciate it, thanks!

I might have just made up that name on the spot.

What I'm trying to do is have a computer that is behind NAT and will need to provide a service connect to a server. Then, I would connect to that server using a third computer and interact with the TCP stream initiated by the first computer, in a way that would work just as if I had connected straight to it.

Found a way to create a forward proxy, which works great: blog.brunogarcia.com/2012/10/simple-tcp-forwarder-in-c.html

using System;
using System.Net;
using System.Net.Sockets;

namespace TcpProxy
{
    class Program
    {
        static void Main(string[] args)
        {
            new TcpForwarderSlim().Start(
    new IPEndPoint(IPAddress.Parse("127.0.0.1"), int.Parse("69")),
    new IPEndPoint(IPAddress.Parse("91.198.174.192"), int.Parse("80")));
        }

    }
    public class TcpForwarderSlim
    {
        private readonly Socket _mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        public void Start(IPEndPoint local, IPEndPoint remote)
        {
            _mainSocket.Bind(local);
            _mainSocket.Listen(10);

            while (true)
            {
                var source = _mainSocket.Accept();
                var destination = new TcpForwarderSlim();
                var state = new State(source, destination._mainSocket);
                destination.Connect(remote, source);
                source.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, OnDataReceive, state);
            }
        }

        private void Connect(EndPoint remoteEndpoint, Socket destination)
        {
            var state = new State(_mainSocket, destination);
            _mainSocket.Connect(remoteEndpoint);
            _mainSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnDataReceive, state);
        }

        private static void OnDataReceive(IAsyncResult result)
        {
            var state = (State)result.AsyncState;
            try
            {
                var bytesRead = state.SourceSocket.EndReceive(result);
                if (bytesRead > 0)
                {
                    state.DestinationSocket.Send(state.Buffer, bytesRead, SocketFlags.None);
                    state.SourceSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, OnDataReceive, state);
                }
            }
            catch
            {
                state.DestinationSocket.Close();
                state.SourceSocket.Close();
            }
        }

        private class State
        {
            public Socket SourceSocket { get; private set; }
            public Socket DestinationSocket { get; private set; }
            public byte[] Buffer { get; private set; }

            public State(Socket source, Socket destination)
            {
                SourceSocket = source;
                DestinationSocket = destination;
                Buffer = new byte[8192];
            }
        }
    }
}

Could anyone point me to the right direction?

Rashawn
  • 9
  • 3

1 Answers1

0

UPNP can open a port on a properly configured router.

STUN, ICE, and TURN use intermediary servers to connect when ports can't be opened. There are open source server implementations.

UDP can use UDP Hole Punching.

This answer provides a more detailed explaination but not much C# help.

Community
  • 1
  • 1
user423430
  • 3,654
  • 3
  • 26
  • 22