'This function handles a BIND request.
The actions taken are:
- create a new socket,
- bind it to the external ip chosen on init of the server,
- listen for a connection on this socket,
- register the bind into the server,
- tell the client the bind is ready,
- accept an incoming connection,
- tell the client the connection is established,
- forward data between the client and the remote peer.'

def handle_bind(self, req):

    remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    remote.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        try:
            remote.bind((self._bindAddy, 0))
            remote.listen(1)
            (socket_ip, socket_port) = remote.getsockname()
        except socket.error:
            (exception, value, traceback) = sys.exc_info()
            if (value[0] == ERR_CONNECTION_RESET_BY_PEER):
                raise Client_Connection_Closed((ERR_CONNECTION_RESET_BY_PEER, socket.errorTab[ERR_CONNECTION_RESET_BY_PEER]))
            else:
                raise Remote_Connection_Failed
        self.answer_granted(socket_ip, socket_port)
        try:
            (read_sock, junk, exception_sock) = select.select([remote], [], [remote], 120)
            if ((read_sock, junk, exception_sock) == ([], [], [])):
                raise Bind_TimeOut_Expired
            if exception_sock:
                raise Remote_Connection_Failed
            (incoming, peer) = remote.accept()
        except:
            raise Remote_Connection_Failed(sys.exc_info())
        try:
            if (peer[0] != req['address'][0]):
                raise Remote_Connection_Failed_Invalid_Host
            self.answer_granted()
            self.forward(self.client_socketet, incoming)
        finally:
            incoming.close()
    finally:
        remote.close()
