"Fossies" - the Fresh Open Source Software Archive

Member "zorp-7.0.4/lib/attach.cc" (28 Oct 2019, 8050 Bytes) of package /linux/privat/zorp-7.0.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "attach.cc" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 7.0.1_vs_7.0.2.

    1 /***************************************************************************
    2  *
    3  * Copyright (c) 2000-2015 BalaBit IT Ltd, Budapest, Hungary
    4  * Copyright (c) 2015-2018 BalaSys IT Ltd, Budapest, Hungary
    5  *
    6  * This program is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2 of the License, or
    9  * (at your option) any later version.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License along
   17  * with this program; if not, write to the Free Software Foundation, Inc.,
   18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   19  *
   20  *
   21  ***************************************************************************/
   22 
   23 #include <zorp/attach.h>
   24 #include <zorpll/connect.h>
   25 #include <zorp/dgram.h>
   26 #include <zorpll/log.h>
   27 #include <zorpll/streamfd.h>
   28 #include <zorp/proxy.h>
   29 #include <zorp/proxygroup.h>
   30 
   31 #include <string.h>
   32 
   33 /*
   34  * Attach - establish outgoing connection
   35  *
   36  */
   37 
   38 struct _ZAttach
   39 {
   40   gchar session_id[MAX_SESSION_ID];
   41   guint proto;
   42   ZProxy *proxy;
   43   ZSockAddr *bind_addr;
   44   ZSockAddr *local;
   45   ZSockAddr *remote;
   46   ZAttachParams params;
   47   ZConnector *connector;
   48   ZConnection *conn;
   49   gboolean connect_finished;
   50   ZAttachCallbackFunc callback;
   51   gpointer user_data;
   52   GDestroyNotify destroy_data;
   53 };
   54 
   55 /**
   56  * z_attach_callback:
   57  * @param self this
   58  * @param conn The connection to add
   59  *
   60  * Internal callback function, called when a connection is established.
   61  * Called from: z_attach_tcp_callback (tcp) or z_attach_start (udp).
   62  */
   63 static void
   64 z_attach_callback(ZStream *fdstream, GError * /* err */, gpointer user_data)
   65 {
   66   ZAttach *self = (ZAttach *) user_data;
   67   gchar buf[256];
   68   ZConnection *conn;
   69 
   70   z_session_enter(self->session_id);
   71 
   72   if (fdstream != NULL)
   73     {
   74       gint fd = z_stream_get_fd(fdstream);
   75 
   76       conn = z_connection_new();
   77       if (z_getsockname(fd, &conn->local, 0) != G_IO_STATUS_NORMAL ||
   78           z_getpeername(fd, &conn->remote, 0) != G_IO_STATUS_NORMAL)
   79         {
   80           z_connection_destroy(conn, FALSE);
   81           z_stream_close(fdstream, NULL);
   82           z_stream_unref(fdstream);
   83           conn = NULL;
   84           goto exit;
   85         }
   86       conn->protocol = self->proto;
   87       conn->stream = fdstream;
   88       conn->dest = z_sockaddr_ref(conn->remote);
   89     }
   90   else
   91     {
   92       conn = NULL;
   93     }
   94 
   95   /*LOG
   96     This message reports that the connection was successfully established.
   97   */
   98   z_log(self->session_id, CORE_DEBUG, 6, "Established connection; %s", z_connection_format(conn, buf, sizeof(buf)));
   99  exit:
  100   if (self->callback)
  101     {
  102       self->callback(conn, self->user_data);
  103     }
  104   else
  105     {
  106       self->conn = conn;
  107       self->connect_finished = TRUE;
  108     }
  109 
  110   z_session_leave(self->session_id);
  111 }
  112 
  113 /**
  114  * z_attach_start:
  115  * @param self this
  116  *
  117  * Initiate establishing a connection
  118  *
  119  * @return TRUE on success
  120  */
  121 static gboolean
  122 z_attach_setup_connector(ZAttach *self)
  123 {
  124   z_session_enter(self->session_id);
  125 
  126   self->conn = NULL;
  127   if (self->proto == ZD_PROTO_TCP)
  128     {
  129       self->connector = z_stream_connector_new(self->session_id, self->bind_addr, self->remote, (self->params.loose ? ZSF_LOOSE_BIND : 0) | (self->params.random ? ZSF_RANDOM_BIND : 0) | ZSF_MARK_TPROXY, z_attach_callback, self, NULL);
  130     }
  131   else  if (self->proto == ZD_PROTO_UDP)
  132     {
  133       self->connector = z_dgram_connector_new(self->session_id, self->bind_addr, self->remote, (self->params.loose ? ZSF_LOOSE_BIND : 0) | (self->params.random ? ZSF_RANDOM_BIND : 0) | ZSF_MARK_TPROXY, z_attach_callback, self, NULL);
  134     }
  135 
  136   if (self->connector)
  137     {
  138       z_connector_set_timeout(self->connector, self->params.timeout < 0 ? -1 : (self->params.timeout + 999) / 1000);
  139       z_connector_set_tos(self->connector, self->params.tos);
  140       z_connector_set_mark(self->connector, self->params.server_socket_mark);
  141     }
  142 
  143   z_session_leave(self->session_id);
  144   return self->connector != NULL;
  145 }
  146 
  147 /**
  148  * z_attach_start:
  149  * @param self this
  150  *
  151  * Initiate establishing a connection
  152  *
  153  * @return TRUE on success
  154  */
  155 gboolean
  156 z_attach_start(ZAttach *self, ZPoll *poll, ZSockAddr **local)
  157 {
  158   gboolean res = FALSE;
  159   ZProxyGroup *proxy_group;
  160   GMainContext *context;
  161 
  162   z_session_enter(self->session_id);
  163 
  164   if (z_attach_setup_connector(self))
  165     {
  166       if (poll)
  167         {
  168           context = z_poll_get_context(poll);
  169         }
  170       else if (self->proxy)
  171         {
  172           proxy_group = z_proxy_get_group(self->proxy);
  173           context = z_proxy_group_get_context(proxy_group);
  174         }
  175       else
  176         {
  177           context = NULL;
  178         }
  179       res = z_connector_start_in_context(self->connector, context, &self->local);
  180       if (res && local)
  181         *local = z_sockaddr_ref(self->local);
  182     }
  183   z_session_leave(self->session_id);
  184   return res;
  185 }
  186 
  187 gboolean
  188 z_attach_start_block(ZAttach *self, ZConnection **conn)
  189 {
  190   ZProxyGroup *proxy_group;
  191   gboolean res = FALSE;
  192 
  193   g_assert(self->callback == NULL);
  194   g_assert(self->connector == NULL);
  195 
  196   *conn = NULL;
  197 
  198   if (self->proxy && self->proxy->flags & ZPF_NONBLOCKING)
  199     {
  200       if (z_attach_start(self, NULL, NULL))
  201         {
  202           proxy_group = z_proxy_get_group(self->proxy);
  203           while (!self->connect_finished && z_proxy_group_iteration(proxy_group))
  204             {
  205               ;
  206             }
  207           *conn = self->conn;
  208           res = TRUE;
  209         }
  210     }
  211   else
  212     {
  213       if (z_attach_setup_connector(self))
  214         {
  215           ZStream *stream;
  216 
  217           if (z_connector_start_block(self->connector, &self->local, &stream))
  218             {
  219               z_attach_callback(stream, NULL, self);
  220               *conn = self->conn;
  221               res = TRUE;
  222             }
  223         }
  224     }
  225   return res;
  226 }
  227 
  228 void
  229 z_attach_cancel(ZAttach *self)
  230 {
  231   if (self->connector)
  232     z_connector_cancel(self->connector);
  233 }
  234 
  235 /**
  236  * z_attach_new:
  237  * @param proxy The proxy instance of the session
  238  * @param bind_addr The address to bind to
  239  * @param remote The address to connect to
  240  * @param params The optional parameters for the connection
  241  * @param callback Callback function to call when the connection is established
  242  * @param notify Callback to call when the structure is destroyed
  243  *
  244  * Allocates and sets up a new instance of ZAttach.
  245  * (For the connection parameters see ZAttachTCPParams and ZAttachUDPParams.)
  246  *
  247  * @return the new instance
  248  */
  249 ZAttach *
  250 z_attach_new(ZProxy *proxy,
  251              guint proto, ZSockAddr *bind_addr, ZSockAddr *remote,
  252              ZAttachParams *params,
  253              ZAttachCallbackFunc callback, gpointer user_data, GDestroyNotify destroy_data)
  254 {
  255   ZAttach *self = g_new0(ZAttach, 1);
  256   gchar *session_id;
  257 
  258   session_id = proxy ? proxy->session_id : NULL;
  259 
  260   z_session_enter(session_id);
  261   g_strlcpy(self->session_id, session_id, sizeof(self->session_id));
  262   if (proxy)
  263     self->proxy = z_proxy_ref(proxy);
  264   else
  265     self->proxy = NULL;
  266   self->proto = proto;
  267   self->bind_addr = z_sockaddr_ref(bind_addr);
  268   self->remote = z_sockaddr_ref(remote);
  269   self->callback = callback;
  270   self->user_data = user_data;
  271   self->destroy_data = destroy_data;
  272   memcpy(&self->params, params, sizeof(self->params));
  273   z_session_leave(self->session_id);
  274   return self;
  275 }
  276 
  277 /**
  278  * z_attach_free:
  279  * @param self this
  280  *
  281  * Free a ZAttach instance,
  282  *
  283  * @return the instance
  284  */
  285 void
  286 z_attach_free(ZAttach *self)
  287 {
  288   if (self)
  289     {
  290       if (self->user_data && self->destroy_data)
  291         {
  292           self->destroy_data(self->user_data);
  293           self->user_data = NULL;
  294         }
  295       if (self->proxy)
  296         z_proxy_unref(self->proxy);
  297       z_connector_unref(self->connector);
  298       z_sockaddr_unref(self->bind_addr);
  299       z_sockaddr_unref(self->local);
  300       z_sockaddr_unref(self->remote);
  301       g_free(self);
  302     }
  303 }