linphone-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Osip] Re: [Linphone-users] not ACKing retransmitted 200's.


From: Simon MORLAT
Subject: Re: [Osip] Re: [Linphone-users] not ACKing retransmitted 200's.
Date: Wed, 29 Oct 2003 09:40:48 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5b) Gecko/20031018 Thunderbird/0.2

Hello Troy,

Here is the patch to be applied on libosip-0.9.7 to add the retransmission support functions. Then linphone's build will automatically recognize the patched version of libosip and the retransmission support will be built. I don't remember exactlly on which version of libosip this patch was generated. If you have troubles in applying it on 0.9.7, you should try older versions.
Regards,
Simon


Troy Cauble wrote:

Troy Cauble wrote:


Greetings,

Using linphone-0.11.0 with osip-0.9.7, I see the following:

 When a 200 is received in response to an INVITE, it is ACKed.
 But if the ACK is lost, the far end (not a linphone) repeats the 200.
 Linphone never ACKs these repeated 200s.

In osip/fsm/ict_fsm.c, ict_rcv_2xx() has two callbacks
to functions in linphone/osipua/src/ict_callbacks.c:
 1) ict_2xx_received() handles the 200 and sends the ACK, and
 2) ict_kill_transaction() frees the transaction

It appears that either ict_rcv_2xx() should not callback
ict_kill_transaction(), or ict_kill_transaction() should
not actually remove the transaction, so that subsequent
200's can be matched.  Can someone suggest which one?
If someone clarifies which library should be responsible,
I can write the code.


OK. Reading the RFC would have helped.  Neither of my guesses
were right.  libosip is fine.  The first 2xx received does
terminate the INVITE.

Subsequent 2xx's should be passed directly to the UA core,
bypassing the transaction layer.


Also, I see OSIP_RETRANSMISSION ifdefs in linphone
for repeating the 200ok msgs until an ACK is received.
But it appears that some osip portions are missing
from 0.9.7.  What's the status of this?

  I find references to these functions
  (osip_start_200ok_retransmissions(), etc.) in osip2.
  Can linphone-0.11.0 (& it's osipua library) be used with osip2 ?
  I thought osip2 was not compatible and you had to wait for an
  eXosip version of linphone.  Or maybe there are cvs entries
  between osip 0.9.7 and 2.0.0 that contain these??



Ah ha!!  This new libosip2 code also catches retransmitted 200ok's,
and retransmits the ACK!!  (Taking on a UA core function!)

So, should I port libosip2 to linphone-0.11.0 (Is it even a port?),
or just port the retransmission portions to libosip-0.9.7 ??

Thanks,
-troy




_______________________________________________
Osip mailing list
address@hidden
http://www.atosc.org/mailinglist/listinfo/osip



? Makefile
? Makefile.in
? aclocal.m4
? autom4te.cache
? config.h
? config.h.in
? config.log
? config.status
? configure
? libtool
? osip-ack-200ok-ret.patch
? osip-ack-200ok-retr.patch
? stamp-h
? conf/Makefile
? conf/Makefile.in
? doc/Makefile
? doc/Makefile.in
? doc/osip.1
? fsm/.deps
? fsm/.libs
? fsm/Makefile
? fsm/Makefile.in
? fsm/dialog.lo
? fsm/fsm_misc.lo
? fsm/ict.lo
? fsm/ict_fsm.lo
? fsm/ist.lo
? fsm/ist_fsm.lo
? fsm/libfsmtl.la
? fsm/nict.lo
? fsm/nict_fsm.lo
? fsm/nist.lo
? fsm/nist_fsm.lo
? fsm/osip.lo
? fsm/port_fifo.lo
? fsm/port_sema.lo
? fsm/port_thread.lo
? fsm/sdp_negoc.lo
? fsm/sipevent.lo
? fsm/transaction.lo
? osip/Makefile
? osip/Makefile.in
? parser/.deps
? parser/.libs
? parser/Makefile
? parser/Makefile.in
? parser/hdr_accept.lo
? parser/hdr_acceptencoding.lo
? parser/hdr_acceptlanguage.lo
? parser/hdr_alertinfo.lo
? parser/hdr_allow.lo
? parser/hdr_authorization.lo
? parser/hdr_body.lo
? parser/hdr_callid.lo
? parser/hdr_callinfo.lo
? parser/hdr_contact.lo
? parser/hdr_contentdisposition.lo
? parser/hdr_contentencoding.lo
? parser/hdr_contentlength.lo
? parser/hdr_contenttype.lo
? parser/hdr_cseq.lo
? parser/hdr_errorinfo.lo
? parser/hdr_from.lo
? parser/hdr_headers.lo
? parser/hdr_mimeversion.lo
? parser/hdr_proxyauthenticate.lo
? parser/hdr_proxyauthorization.lo
? parser/hdr_recordroute.lo
? parser/hdr_route.lo
? parser/hdr_to.lo
? parser/hdr_via.lo
? parser/hdr_wwwauthenticate.lo
? parser/libosip.la
? parser/md5c.lo
? parser/msg_cparser.lo
? parser/msg_parser.lo
? parser/msg_read.lo
? parser/msg_write.lo
? parser/port_list.lo
? parser/port_malloc.lo
? parser/port_misc.lo
? parser/sdp_accessor.lo
? parser/sdp_rfc2327.lo
? parser/urls.lo
? scripts/Makefile
? scripts/Makefile.in
? scripts/config.guess
? scripts/config.sub
? scripts/ltmain.sh
? test/.deps
? test/.libs
? test/Makefile
? test/Makefile.in
? test/tcallid
? test/tcontact
? test/tcontentt
? test/tfrom
? test/torture_sdp_test
? test/torture_test
? test/trecordr
? test/troute
? test/tto
? test/turl
? test/tvia
? test/twwwa
? windows/Makefile
? windows/Makefile.in
Index: fsm/dialog.c
===================================================================
RCS file: /cvsroot/osip/osip/fsm/dialog.c,v
retrieving revision 1.18
diff -r1.18 dialog.c
487a488
> 
Index: fsm/osip.c
===================================================================
RCS file: /cvsroot/osip/osip/fsm/osip.c,v
retrieving revision 1.22
diff -r1.22 osip.c
21a22
> #include <osip/dialog.h>
29a31
> static smutex_t *ixt_fastmutex;
52a55
>   ixt_fastmutex = smutex_init();
76a80,313
> 
> int osip_ixt_lock(osip_t *osip)
> {
> #ifdef OSIP_MT
>   return smutex_lock (ixt_fastmutex);
> #else
>   return 0;
> #endif
> }
> 
> int osip_ixt_unlock(osip_t *osip)
> {
> #ifdef OSIP_MT
>   return smutex_unlock (ixt_fastmutex);
> #else
>   return 0;
> #endif
> }
> 
> /* these are for transactions that would need retransmission not handled by 
> state machines */
> void osip_add_ixt(osip_t *osip, ixt_t * ixt)
> {
>       /* ajout dans la liste de osip_t->ixt */
>       #ifdef OSIP_MT
>       smutex_lock(ixt_fastmutex);
>       #endif
>       list_add(osip->ixt_retransmissions,(void*)ixt,0);
>       #ifdef OSIP_MT
>       smutex_unlock(ixt_fastmutex);
>       #endif
> 
> }
> 
> void osip_remove_ixt(osip_t *osip, ixt_t * ixt)
> {
>       int i=0;
>       int found=0;
>       ixt_t *tmp;
>       /* ajout dans la liste de osip_t->ixt */
> #ifdef OSIP_MT
>       smutex_lock(ixt_fastmutex);
> #endif
>       for(i=0;!list_eol(osip->ixt_retransmissions,i);i++){
>               tmp=(ixt_t*)list_get(osip->ixt_retransmissions,i);
>               if (tmp==ixt){
>                       list_remove(osip->ixt_retransmissions,i);
>                       found=1;
>                       break;
>               }
>       }
> #ifdef OSIP_MT
>       smutex_unlock(ixt_fastmutex);
> #endif
> }
> 
> 
> void response_get_destination(sip_t *response, char **address, int *portnum)
> {
>       via_t *via;
>       char *host=NULL;
>       int port=0;
>       
>       via = (via_t *) list_get (response->vias, 0);
>       if (via)
>     {
>               
>               generic_param_t *maddr;
>               generic_param_t *received;
>               generic_param_t *rport;
>               via_param_getbyname (via, "maddr", &maddr);
>               via_param_getbyname (via, "received", &received);
>               via_param_getbyname (via, "rport", &rport);
>               /* 1: user should not use the provided information
>          (host and port) if they are using a reliable
>          transport. Instead, they should use the already
>          open socket attached to this transaction. */
>               /* 2: check maddr and multicast usage */
>               if (maddr != NULL)
>                       host = maddr->gvalue;
>               /* we should check if this is a multicast address and use
>          set the "ttl" in this case. (this must be done in the
>          UDP message (not at the SIP layer) */
>               else if (received != NULL)
>                       host = received->gvalue;
>               else
>                       host = via->host;
> 
>               if (rport == NULL || rport->gvalue == NULL)
>               {
>                       if (via->port != NULL)
>                               port = satoi (via->port);
>                       else
>                               port = 5060;
>               }
>               else
>                       port = satoi (rport->gvalue);
>     }
>       *portnum=port;
>       if (host!=NULL) *address=sgetcopy(host);
>       else *address=NULL;
> }
> 
> 
> int ixt_init(ixt_t **ixt)
> {
>       ixt_t *pixt;
>       *ixt=pixt=smalloc(sizeof(ixt_t));
>       pixt->dialog=NULL;
>       pixt->msg2xx=NULL;
>       pixt->ack=NULL;
>       pixt->start=time(NULL);
>       pixt->interval=500;
>       pixt->counter=7;
>       pixt->dest=NULL;
>       pixt->port=5060;
>       pixt->sock=-1;
>       return 0;
> }
> 
> void ixt_free(ixt_t *ixt)
> {
>       if (ixt->ack!=NULL) {
>               msg_free(ixt->ack);
>               sfree(ixt->ack);
>       }
>       if (ixt->msg2xx!=NULL) {
>               msg_free(ixt->msg2xx);
>               sfree(ixt->msg2xx);
>       }
>       sfree(ixt->dest);
> }
> 
> /* usefull for UAs */
> void osip_start_200ok_retransmissions(osip_t *osip, dialog_t *dialog, sip_t 
> *msg200ok, int sock)
> {
>       ixt_t *ixt;
>       ixt_init(&ixt);
>       ixt->dialog=dialog;
>       msg_clone(msg200ok,&ixt->msg2xx);
>       ixt->sock=sock;
>       response_get_destination(msg200ok,&ixt->dest,&ixt->port);
>       osip_add_ixt(osip,ixt);
> }
> 
> 
> void osip_start_ack_retransmissions(osip_t *osip, dialog_t *dialog, sip_t 
> *ack, char *dest, int port, int sock)
> {
>       ixt_t *ixt;
>       ixt_init(&ixt);
>       ixt->dialog=dialog;
>       msg_clone(ack,&ixt->ack);
>       ixt->dest=sgetcopy(dest);
>       ixt->port=port;
>       ixt->sock=sock;
>       osip_add_ixt(osip,ixt);
> }
> 
> /* we stop the 200ok when receiving the corresponding ack */
> void osip_stop_200ok_retransmissions(osip_t *osip, sip_t *ack)
> {
>       int i;
>       ixt_t *ixt;
>       osip_ixt_lock(osip);
>       for (i=0;!list_eol(osip->ixt_retransmissions,i);i++){
>               ixt=(ixt_t*)list_get(osip->ixt_retransmissions,i);
>               if (dialog_match_as_uas(ixt->dialog,ack)==0){
>                       list_remove(osip->ixt_retransmissions,i);
>                       ixt_free(ixt);
>                       sfree(ixt);
>                       break;
>               }
>       }
>       osip_ixt_unlock(osip);
> }
> 
> /* when a dialog is destroyed by the application, it is safer to remove all 
> ixt that are 
>       related to it */
> void osip_stop_retransmissions_from_dialog(osip_t *osip, dialog_t *dialog)
> {
>       int i;
>       ixt_t *ixt;
>       osip_ixt_lock(osip);
>       for (i=0;!list_eol(osip->ixt_retransmissions,i);i++){
>               ixt=(ixt_t*)list_get(osip->ixt_retransmissions,i);
>               if (ixt->dialog==dialog){
>                       list_remove(osip->ixt_retransmissions,i);
>                       ixt_free(ixt);
>                       sfree(ixt);
>                       i--;
>               }
>       }
>       osip_ixt_unlock(osip);
> }
> 
> 
> void ixt_retransmit(osip_t *osip,ixt_t *ixt, time_t current)
> {
>       if ( (current-ixt->start)*1000 > ixt->interval){
>               ixt->interval=ixt->interval*2;
>               ixt->start=current;
>               if (ixt->ack!=NULL)
>                       osip->cb_send_message (NULL, ixt->ack,
>                          ixt->dest,ixt->port, ixt->sock);
>               else if (ixt->msg2xx!=NULL)
>                       osip->cb_send_message (NULL, ixt->msg2xx,
>                          ixt->dest,ixt->port, ixt->sock);
>               ixt->counter--;
>       }
> }
> 
> void osip_retransmissions_execute(osip_t *osip)
> {
>       int i;
>       time_t current;
>       ixt_t *ixt;
>       current=time(NULL);
>       osip_ixt_lock(osip);
>       for (i=0;!list_eol(osip->ixt_retransmissions,i);i++){
>               ixt=(ixt_t*)list_get(osip->ixt_retransmissions,i);
>               ixt_retransmit(osip,ixt,current);
>               if (ixt->counter==0){
>                       /* remove it */
>                       list_remove(osip->ixt_retransmissions,i);
>                       ixt_free(ixt);
>                       sfree(ixt);
>                       i--;
>               }
>       }
>       osip_ixt_unlock(osip);
> }
> 
> 
> 
> 
770c1007,1008
< 
---
>   (*osip)->ixt_retransmissions = (list_t *) smalloc (sizeof (list_t));
>   list_init ((*osip)->ixt_retransmissions);
Index: fsm/transaction.c
===================================================================
RCS file: /cvsroot/osip/osip/fsm/transaction.c,v
retrieving revision 1.21
diff -r1.21 transaction.c
882a883
> 
Index: osip/dialog.h
===================================================================
RCS file: /cvsroot/osip/osip/osip/dialog.h,v
retrieving revision 1.8
diff -r1.8 dialog.h
24c24,25
< #include <osip/port.h>
---
> //#include <osip/port.h>
> #include <osip/list.h>
Index: osip/osip.h
===================================================================
RCS file: /cvsroot/osip/osip/osip/osip.h,v
retrieving revision 1.19
diff -r1.19 osip.h
34a35
> 
339a341,342
> #include <osip/dialog.h>
>   
524a528,544
>   typedef struct ixt_t ixt_t;
>         
> 
>   struct ixt_t
>   {
>         /* any ACK received that match this context will set counter to -1*/
>        struct dialog_t *dialog;
>        sip_t *msg2xx;    /* copy of string to retransmit */
>        sip_t *ack;    /* useless for ist */
>        time_t start;
>        int interval; /* between each retransmission, in ms */
>        char *dest;
>        int port;
>        int sock;
>        int counter;  /* start at 7 */
>   };
>   
585a606,608
>       list_t *ixt_retransmissions;    /*optionnal list of ixt_t that contains 
> information about
>                                         some message that need some 
> retransmission
>                                                                 not handled 
> by state machines */
689c712
< 
---
>   
872a896,949
> 
> /**
>  * Create a context for out of state-machines retransmissions. Internal only.
>  *
>  */
> int ixt_init(ixt_t **ixt);
> 
> void ixt_free(ixt_t *ixt);
> 
> void osip_add_ixt(osip_t *osip, ixt_t * ixt);
> 
> void osip_remove_ixt(osip_t *osip, ixt_t * ixt);
> 
> void osip_retransmissions_execute(osip_t *osip);
> 
> /**
>  * Start out of fsm 200 Ok retransmissions. This is usefull for user-agents.
>  * @param osip The osip_t structure.
>  * @param dialog The dialog the 200 Ok is part of.
>  * @param msg200ok The 200 ok response.
>  * @param sock The socket to be used to send the message. (optional).
>  */
> void osip_start_200ok_retransmissions(osip_t *osip, dialog_t *dialog, sip_t 
> *msg200ok, int sock);
> 
> 
> /**
>  * Start out of fsm ACK retransmissions. This is usefull for user-agents.
>  * @param osip The osip_t structure.
>  * @param dialog The dialog the ACK is part of.
>  * @param ack The ACK that has just been sent in response to a 200 Ok.
>  * @param dest The destination host.
>  * @param sock The destination port.
>  * @param sock The socket to be used to send the message. (optional).
>  */
> void osip_start_ack_retransmissions(osip_t *osip, dialog_t *dialog, sip_t 
> *ack, char *dest, int port, int sock);
> 
> 
> /**
>  * Stop the out of fsm 200 Ok retransmissions matching an incoming ACK.
>  * @param osip The osip_t structure.
>  * @param ack  The ack that has just been received.
>  */
> void osip_stop_200ok_retransmissions(osip_t *osip, sip_t *ack);
> 
> 
> /**
>  * Stop out of fsm retransmissions (ACK or 200 Ok) associated to a given 
> dialog.
>  * This function must be called before freeing a dialog if out of fsm 
> retransmissions
>  * have been scheduled.
>  * @param osip The osip_t structure
>  * @param dialog The dialog.
>  */
> void osip_stop_retransmissions_from_dialog(osip_t *osip, dialog_t *dialog);
> 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]