[PATCH] : ir245_clean_listen.diff

From: Jean Tourrilhes (jt@bougret.hpl.hp.com)
Date: Fri Nov 30 2001 - 15:57:05 EST


ir245_clean_listen.diff :
-----------------------
        o [FEATURE] Put the code to set the socket back to listen mode in
          common functions instead of cut'n'pasted all over the place.
        o [CRITICA] When setting a socket back to listen mode, set
          self->tsap->lsap->lap = NULL; to avoid crashing is LAP is
          removed before the socket.
        o [CORRECT] Fix disconnect event generation. Doh !

diff -u -p linux/include/net/irda/irlmp.d3.h linux/include/net/irda/irlmp.h
--- linux/include/net/irda/irlmp.d3.h Thu Nov 29 10:33:26 2001
+++ linux/include/net/irda/irlmp.h Thu Nov 29 11:04:59 2001
@@ -264,4 +264,16 @@ static inline int irlmp_get_lap_tx_queue
         return IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap);
 }
 
+/* After doing a irlmp_dup(), this get one of the two socket back into
+ * a state where it's waiting incomming connections.
+ * Note : this can be used *only* if the socket is not yet connected
+ * (i.e. NO irlmp_connect_response() done on this socket).
+ * - Jean II */
+static inline void irlmp_listen(struct lsap_cb *self)
+{
+ self->dlsap_sel = LSAP_ANY;
+ self->lap = NULL;
+ self->lsap_state = LSAP_DISCONNECTED;
+}
+
 #endif
diff -u -p linux/include/net/irda/irttp.d3.h linux/include/net/irda/irttp.h
--- linux/include/net/irda/irttp.d3.h Thu Nov 29 11:02:29 2001
+++ linux/include/net/irda/irttp.h Thu Nov 29 11:10:51 2001
@@ -148,6 +148,17 @@ static __inline __u32 irttp_get_max_seg_
         return self->max_seg_size;
 }
 
+/* After doing a irttp_dup(), this get one of the two socket back into
+ * a state where it's waiting incomming connections.
+ * Note : this can be used *only* if the socket is not yet connected
+ * (i.e. NO irttp_connect_response() done on this socket).
+ * - Jean II */
+static inline void irttp_listen(struct tsap_cb *self)
+{
+ irlmp_listen(self->lsap);
+ self->dtsap_sel = LSAP_ANY;
+}
+
 extern struct irttp_cb *irttp;
 
 #endif /* IRTTP_H */
diff -u -p linux/net/irda/irlmp.d3.c linux/net/irda/irlmp.c
--- linux/net/irda/irlmp.d3.c Tue Nov 20 11:21:44 2001
+++ linux/net/irda/irlmp.c Thu Nov 29 10:57:04 2001
@@ -469,7 +469,12 @@ void irlmp_connect_indication(struct lsa
 
         IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",
                    self->slsap_sel, self->dlsap_sel);
-
+
+ /* Note : self->lap is set in irlmp_link_data_indication(),
+ * (case CONNECT_CMD:) because we have no way to set it here.
+ * Similarly, self->dlsap_sel is usually set in irlmp_find_lsap().
+ * Jean II */
+
         self->qos = *self->lap->qos;
 
         max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
@@ -577,7 +582,9 @@ struct lsap_cb *irlmp_dup(struct lsap_cb
         /* Dup */
         memcpy(new, orig, sizeof(struct lsap_cb));
         new->notify.instance = instance;
-
+ /* new->lap = orig->lap; => done in the memcpy() */
+ /* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */
+
         init_timer(&new->watchdog_timer);
         
         hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new, (int) new,
diff -u -p linux/net/irda/iriap.d3.c linux/net/irda/iriap.c
--- linux/net/irda/iriap.d3.c Thu Nov 29 11:12:55 2001
+++ linux/net/irda/iriap.c Thu Nov 29 11:13:25 2001
@@ -800,9 +800,7 @@ static void iriap_connect_indication(voi
         new->max_header_size = max_header_size;
 
         /* Clean up the original one to keep it in listen state */
- self->lsap->dlsap_sel = LSAP_ANY;
- self->lsap->lsap_state = LSAP_DISCONNECTED;
- /* FIXME: refcount in irlmp might get wrong */
+ irlmp_listen(self->lsap);
         
         iriap_do_server_event(new, IAP_LM_CONNECT_INDICATION, userdata);
 }
diff -u -p linux/net/irda/af_irda.d3b.c linux/net/irda/af_irda.c
--- linux/net/irda/af_irda.d3b.c Thu Nov 29 11:09:09 2001
+++ linux/net/irda/af_irda.c Thu Nov 29 11:09:36 2001
@@ -914,8 +914,7 @@ static int irda_accept(struct socket *so
         memcpy(&new->qos_tx, &self->qos_tx, sizeof(struct qos_info));
 
         /* Clean up the original one to keep it in listen state */
- self->tsap->dtsap_sel = self->tsap->lsap->dlsap_sel = LSAP_ANY;
- self->tsap->lsap->lsap_state = LSAP_DISCONNECTED;
+ irttp_listen(self->tsap);
 
         skb->sk = NULL;
         skb->destructor = NULL;
diff -u -p linux/net/irda/irnet/irnet.d3.h linux/net/irda/irnet/irnet.h
--- linux/net/irda/irnet/irnet.d3.h Wed Nov 28 10:15:54 2001
+++ linux/net/irda/irnet/irnet.h Thu Nov 29 11:15:57 2001
@@ -199,6 +199,13 @@
  * o Avoid leaking discovery log and skb
  * o Replace "self" with "server" in irnet_connect_indication() to
  * better detect cut'n'paste error ;-)
+ *
+ * v9 - 29.11.01 - Jean II
+ * o Fix event generation in disconnect indication that I broke in v8
+ * It was always generation "No-Answer" because I was testing ttp_open
+ * just after clearing it. *blush*.
+ * o Use newly created irttp_listen() to fix potential crash when LAP
+ * destroyed before irnet module removed.
  */
 
 /***************************** INCLUDES *****************************/
diff -u -p linux/net/irda/irnet/irnet_irda.d3.c linux/net/irda/irnet/irnet_irda.c
--- linux/net/irda/irnet/irnet_irda.d3.c Tue Nov 27 16:19:28 2001
+++ linux/net/irda/irnet/irnet_irda.c Thu Nov 29 11:50:00 2001
@@ -830,8 +830,7 @@ irnet_connect_socket(irnet_socket * serv
 #endif /* STREAM_COMPAT */
 
   /* Clean up the original one to keep it in listen state */
- server->tsap->dtsap_sel = server->tsap->lsap->dlsap_sel = LSAP_ANY;
- server->tsap->lsap->lsap_state = LSAP_DISCONNECTED;
+ irttp_listen(server->tsap);
 
   /* Send a connection response on the new socket */
   irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL);
@@ -897,8 +896,7 @@ irnet_disconnect_server(irnet_socket * s
                    self->saddr, self->daddr, self->rname);
 
   /* Clean up the server to keep it in listen state */
- self->tsap->dtsap_sel = self->tsap->lsap->dlsap_sel = LSAP_ANY;
- self->tsap->lsap->lsap_state = LSAP_DISCONNECTED;
+ irttp_listen(self->tsap);
 
   DEXIT(IRDA_SERV_TRACE, "\n");
   return;
@@ -1081,7 +1079,8 @@ irnet_disconnect_indication(void * insta
                             struct sk_buff *skb)
 {
   irnet_socket * self = (irnet_socket *) instance;
- int test = 0;
+ int test_open;
+ int test_connect;
 
   DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
   DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
@@ -1091,23 +1090,23 @@ irnet_disconnect_indication(void * insta
     dev_kfree_skb(skb);
 
   /* Prevent higher layer from accessing IrTTP */
- test = test_and_clear_bit(0, &self->ttp_open);
+ test_open = test_and_clear_bit(0, &self->ttp_open);
   /* Not connecting anymore...
    * (note : TSAP is open, so IAP callbacks are no longer pending...) */
- test |= test_and_clear_bit(0, &self->ttp_connect);
+ test_connect = test_and_clear_bit(0, &self->ttp_connect);
 
   /* If both self->ttp_open and self->ttp_connect are NULL, it mean that we
    * have a race condition with irda_irnet_destroy() or
    * irnet_connect_indication(), so don't mess up tsap...
    */
- if(!test)
+ if(!(test_open || test_connect))
     {
       DERROR(IRDA_CB_ERROR, "Race condition detected...\n");
       return;
     }
 
   /* If we were active, notify the control channel */
- if(test_bit(0, &self->ttp_open))
+ if(test_open)
     irnet_post_event(self, IRNET_DISCONNECT_FROM,
                      self->saddr, self->daddr, self->rname);
   else
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Nov 30 2001 - 21:00:40 EST