ppp: Refactor server-side API
authorDenis Kenzior <denkenz@gmail.com>
Tue, 29 Jun 2010 16:53:11 +0000 (11:53 -0500)
committerDenis Kenzior <denkenz@gmail.com>
Tue, 29 Jun 2010 16:53:11 +0000 (11:53 -0500)
The biggest update here is that the server needs to be in dormant mode
by default, so as not to send a Configure-Req to the peer until the peer
is ready.  This requires adding special constructor for LCP to
initialize it to Stopped state instead of initial state.

Along with this, we pass the server local IP directly to the ppp server
constructor.

gatchat/gatppp.c
gatchat/gatppp.h
gatchat/ppp.h
gatchat/ppp_cp.c
gatchat/ppp_cp.h
gatchat/ppp_ipcp.c
gatchat/ppp_lcp.c

index e7a9f19..1d41ded 100644 (file)
@@ -479,7 +479,7 @@ void g_at_ppp_set_server_info(GAtPPP *ppp, const char *remote,
        ipcp_set_server_info(ppp->ipcp, r, d1, d2);
 }
 
-static GAtPPP *ppp_init_common(GAtHDLC *hdlc)
+static GAtPPP *ppp_init_common(GAtHDLC *hdlc, gboolean is_server, guint32 ip)
 {
        GAtPPP *ppp;
 
@@ -496,15 +496,18 @@ static GAtPPP *ppp_init_common(GAtHDLC *hdlc)
        ppp->mtu = DEFAULT_MTU;
 
        /* initialize the lcp state */
-       ppp->lcp = lcp_new(ppp);
+       ppp->lcp = lcp_new(ppp, is_server);
 
        /* initialize IPCP state */
-       ppp->ipcp = ipcp_new(ppp);
+       ppp->ipcp = ipcp_new(ppp, is_server, ip);
 
        g_at_hdlc_set_receive(ppp->hdlc, ppp_receive, ppp);
        g_at_io_set_disconnect_function(g_at_hdlc_get_io(ppp->hdlc),
                                                io_disconnect, ppp);
 
+       if (is_server)
+               ppp_enter_phase(ppp, PPP_PHASE_ESTABLISHMENT);
+
        return ppp;
 }
 
@@ -517,7 +520,7 @@ GAtPPP *g_at_ppp_new(GIOChannel *modem)
        if (hdlc == NULL)
                return NULL;
 
-       ppp = ppp_init_common(hdlc);
+       ppp = ppp_init_common(hdlc, FALSE, 0);
        g_at_hdlc_unref(hdlc);
 
        return ppp;
@@ -532,7 +535,49 @@ GAtPPP *g_at_ppp_new_from_io(GAtIO *io)
        if (hdlc == NULL)
                return NULL;
 
-       ppp = ppp_init_common(hdlc);
+       ppp = ppp_init_common(hdlc, FALSE, 0);
+       g_at_hdlc_unref(hdlc);
+
+       return ppp;
+}
+
+GAtPPP *g_at_ppp_server_new(GIOChannel *modem, const char *local)
+{
+       GAtHDLC *hdlc;
+       GAtPPP *ppp;
+       guint32 ip;
+
+       if (local == NULL)
+               ip = 0;
+       else if (inet_pton(AF_INET, local, &ip) != 1)
+               return NULL;
+
+       hdlc = g_at_hdlc_new(modem);
+       if (hdlc == NULL)
+               return NULL;
+
+       ppp = ppp_init_common(hdlc, TRUE, ip);
+       g_at_hdlc_unref(hdlc);
+
+       return ppp;
+}
+
+GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local)
+{
+       GAtHDLC *hdlc;
+       GAtPPP *ppp;
+       guint32 ip;
+
+       if (local == NULL)
+               ip = 0;
+       else if (inet_pton(AF_INET, local, &ip) != 1)
+               return NULL;
+
+       hdlc = g_at_hdlc_new_from_io(io);
+       if (hdlc == NULL)
+               return NULL;
+
+       ppp = ppp_init_common(hdlc, TRUE, ip);
        g_at_hdlc_unref(hdlc);
 
        return ppp;
index 450a26d..fb5de4c 100644 (file)
@@ -52,6 +52,9 @@ typedef void (*GAtPPPDisconnectFunc)(GAtPPPDisconnectReason reason,
 
 GAtPPP *g_at_ppp_new(GIOChannel *modem);
 GAtPPP *g_at_ppp_new_from_io(GAtIO *io);
+GAtPPP *g_at_ppp_server_new(GIOChannel *modem, const char *local);
+GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local);
+
 void g_at_ppp_open(GAtPPP *ppp);
 void g_at_ppp_set_connect_function(GAtPPP *ppp, GAtPPPConnectFunc callback,
                                        gpointer user_data);
index d815b9f..01ab8e0 100644 (file)
@@ -79,12 +79,12 @@ static inline void __put_unaligned_short(void *p, guint16 val)
        (get_host_short(packet + 2))
 
 /* LCP related functions */
-struct pppcp_data *lcp_new(GAtPPP *ppp);
+struct pppcp_data *lcp_new(GAtPPP *ppp, gboolean dormant);
 void lcp_free(struct pppcp_data *lcp);
 void lcp_protocol_reject(struct pppcp_data *lcp, guint8 *packet, gsize len);
 
 /* IPCP related functions */
-struct pppcp_data *ipcp_new(GAtPPP *ppp);
+struct pppcp_data *ipcp_new(GAtPPP *ppp, gboolean is_server, guint32 ip);
 void ipcp_free(struct pppcp_data *data);
 void ipcp_set_server_info(struct pppcp_data *ipcp, guint32 peer_addr,
                                guint32 dns1, guint32 dns2);
index b0a18aa..647e241 100644 (file)
@@ -996,7 +996,8 @@ void pppcp_set_local_options(struct pppcp_data *pppcp,
        pppcp->local_options_len = len;
 }
 
-struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto)
+struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto,
+                               gboolean dormant)
 {
        struct pppcp_data *data;
 
@@ -1004,7 +1005,11 @@ struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto)
        if (!data)
                return NULL;
 
-       data->state = INITIAL;
+       if (dormant)
+               data->state = STOPPED;
+       else
+               data->state = INITIAL;
+
        data->config_timer_data.restart_interval = INITIAL_RESTART_TIMEOUT;
        data->terminate_timer_data.restart_interval = INITIAL_RESTART_TIMEOUT;
        data->config_timer_data.max_counter = MAX_CONFIGURE;
index 4dbc86e..56a20e0 100644 (file)
@@ -103,7 +103,8 @@ guint8 ppp_option_iter_get_type(struct ppp_option_iter *iter);
 guint8 ppp_option_iter_get_length(struct ppp_option_iter *iter);
 const guint8 *ppp_option_iter_get_data(struct ppp_option_iter *iter);
 
-struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto);
+struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto,
+                               gboolean dormant);
 void pppcp_free(struct pppcp_data *data);
 
 void pppcp_set_data(struct pppcp_data *pppcp, gpointer data);
index 7d59a4b..f345607 100644 (file)
@@ -316,7 +316,7 @@ static enum rcr_result ipcp_server_rcr(struct ipcp_data *ipcp,
        struct ppp_option_iter iter;
        guint8 nak_options[MAX_CONFIG_OPTION_SIZE];
        guint16 len = 0;
-       guint8 *rej_options;
+       guint8 *rej_options = NULL;
        guint16 rej_len = 0;
        guint32 addr;
 
@@ -462,7 +462,7 @@ struct pppcp_proto ipcp_proto = {
        .rcr                    = ipcp_rcr,
 };
 
-struct pppcp_data *ipcp_new(GAtPPP *ppp)
+struct pppcp_data *ipcp_new(GAtPPP *ppp, gboolean is_server, guint32 ip)
 {
        struct ipcp_data *ipcp;
        struct pppcp_data *pppcp;
@@ -471,7 +471,7 @@ struct pppcp_data *ipcp_new(GAtPPP *ppp)
        if (!ipcp)
                return NULL;
 
-       pppcp = pppcp_new(ppp, &ipcp_proto);
+       pppcp = pppcp_new(ppp, &ipcp_proto, FALSE);
        if (!pppcp) {
                g_printerr("Failed to allocate PPPCP struct\n");
                g_free(ipcp);
@@ -479,7 +479,14 @@ struct pppcp_data *ipcp_new(GAtPPP *ppp)
        }
 
        pppcp_set_data(pppcp, ipcp);
-       ipcp_reset_client_config_options(ipcp);
+       ipcp->is_server = is_server;
+
+       if (is_server) {
+               ipcp->local_addr = ip;
+               ipcp_reset_server_config_options(ipcp);
+       } else
+               ipcp_reset_client_config_options(ipcp);
+
        pppcp_set_local_options(pppcp, ipcp->options, ipcp->options_len);
 
        return pppcp;
index 2a5370b..3cfab5c 100644 (file)
@@ -304,7 +304,7 @@ void lcp_free(struct pppcp_data *pppcp)
        pppcp_free(pppcp);
 }
 
-struct pppcp_data *lcp_new(GAtPPP *ppp)
+struct pppcp_data *lcp_new(GAtPPP *ppp, gboolean is_server)
 {
        struct pppcp_data *pppcp;
        struct lcp_data *lcp;
@@ -313,7 +313,7 @@ struct pppcp_data *lcp_new(GAtPPP *ppp)
        if (!lcp)
                return NULL;
 
-       pppcp = pppcp_new(ppp, &lcp_proto);
+       pppcp = pppcp_new(ppp, &lcp_proto, is_server);
        if (!pppcp) {
                g_free(lcp);
                return NULL;