Navigation


source: freeDiameter/extensions/app_sip/registrationtermination.c @ 706:4ffbc9f1e922

Last change on this file since 706:4ffbc9f1e922 was 706:4ffbc9f1e922, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 11 years ago

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File size: 9.9 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Alexandre Westfahl <awestfahl@freediameter.net>                                                *
4*                                                                                                        *
5* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project.    *             
6*                                                                                                        *
7* All rights reserved.                                                                                   *
8*                                                                                                        *
9* Redistribution and use of this software in source and binary forms, with or without modification, are  *
10* permitted provided that the following conditions are met:                                              *
11*                                                                                                        *
12* * Redistributions of source code must retain the above                                                 *
13*   copyright notice, this list of conditions and the                                                    *
14*   following disclaimer.                                                                                *
15*                                                                                                        *
16* * Redistributions in binary form must reproduce the above                                              *
17*   copyright notice, this list of conditions and the                                                    *
18*   following disclaimer in the documentation and/or other                                               *
19*   materials provided with the distribution.                                                            *
20*                                                                                                        *
21* * Neither the name of the Teraoka Laboratory nor the                                                   *
22*   names of its contributors may be used to endorse or                                                  *
23*   promote products derived from this software without                                                  *
24*   specific prior written permission of Teraoka Laboratory                                              *
25*                                                                                                        *
26*                                                                                                        *
27* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
28* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
29* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
30* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT     *
31* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
32* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
33* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
34* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                             *
35*********************************************************************************************************/
36#include "app_sip.h"
37#include <sys/types.h>
38#include <sys/socket.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41#include <unistd.h>
42typedef int SOCKET;
43typedef struct sockaddr_in SOCKADDR_IN;
44typedef struct sockaddr SOCKADDR;
45
46//Procedure which always wait for data on socket
47void *rtr_socket(void *arg)
48{
49        SOCKET sock;
50        SOCKADDR_IN sin, csin;
51        struct rtrsipaor rtrsip;
52        int rcvbytes=0;
53        sock = socket(AF_INET, SOCK_STREAM, 0);
54        sin.sin_addr.s_addr = inet_addr("127.0.0.1");
55        sin.sin_family = AF_INET;
56        sin.sin_port = htons(as_conf->rtr_port);
57        socklen_t sinsize = sizeof(csin);
58        int accepted=0;
59
60        if(!bind(sock, (SOCKADDR*)&sin, sizeof(sin)))
61        {
62                if(listen(sock,1))
63                {
64                        TRACE_DEBUG(INFO,"ERROR on listen!");
65                }
66               
67                while(1)
68                {
69                        accepted=accept(sock, (struct sockaddr *)&csin,&sinsize);
70                        if(accepted>-1)
71                        {
72                                rcvbytes=recv(accepted, &rtrsip, sizeof(struct rtrsipaor),0);
73                               
74                                if(rcvbytes>-1)
75                                {
76                                        //We received something, we can send an RTR
77                                        app_sip_RTR_cb(rtrsip);
78                                }
79                        }
80                }
81        }
82        else
83                TRACE_DEBUG(INFO,"Can't create socket!");
84
85       
86        pthread_exit(NULL);
87       
88}
89//Called to send a RTR
90int app_sip_RTR_cb(struct rtrsipaor structure)
91{
92        TRACE_ENTRY("%p", structure);
93       
94        int got_username=0;
95        int got_streason=0;
96        int num_aor=0;//How many SIP-AOR?
97        struct dict_object * rtr_model=NULL;
98        struct msg * message=NULL;
99        struct avp *groupedavp=NULL, *avp=NULL;
100        struct session *sess=NULL;
101        union avp_value value;
102       
103        //We must check that we have all needed value in structure
104        if(structure.username[0]!='\0')
105                got_username=1;
106       
107        if(structure.sip_aor1[0]!='\0')
108        {       
109                num_aor++;
110                if(structure.sip_aor2[0]!='\0')
111                {
112                        num_aor++;
113                        if(structure.sip_aor3[0]!='\0')
114                                num_aor++;
115                }
116        }
117       
118        if(structure.strreason!='\0')
119                got_streason=1;
120       
121       
122        TRACE_DEBUG(FULL,"Request for %d SIP_AOR to be deregistred.",num_aor);
123       
124        if((got_username + num_aor)==0)
125        {
126                //We must have a least a SIP_AOR or a Username
127                TRACE_DEBUG(INFO,"Can not proceed because there is no SIP_AOR or Username");
128                return EINVAL;
129        }
130        if(structure.reason<0)
131        {
132                //We must have a least a SIP_AOR or a Username
133                TRACE_DEBUG(INFO,"Incorrect Reason-Code");
134                return EINVAL;
135        }
136       
137        if(structure.desthost[0]=='\0')
138        {
139                //We must have a least a SIP_AOR or a Username
140                TRACE_DEBUG(INFO,"No Destination_Host was provided!");
141                return EINVAL;
142        }
143        //Create the base message for an RTR
144        CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &rtr_model, ENOENT) );
145        CHECK_FCT( fd_msg_new (rtr_model, 0, &message));
146       
147        // Create a new session
148        {
149                #define APP_SIP_SID_OPT  "app_sip"
150                CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)APP_SIP_SID_OPT, CONSTSTRLEN(APP_SIP_SID_OPT) ));
151                os0_t sid;
152                size_t sidlen;
153                CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
154                CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
155                value.os.data = sid;
156                value.os.len  = sidlen;
157                CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
158                CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
159        }
160       
161        //Add the Auth-Application-Id
162        {
163                CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
164                value.i32 = 6;
165                CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
166                CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
167        }
168       
169        //Auth_Session_State
170        {
171                CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
172                value.i32=1;
173                CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
174                CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
175        }
176       
177        //Origin_Host & Origin_Realm
178        CHECK_FCT( fd_msg_add_origin ( message, 0 ));
179       
180        //Destination_Host
181        {
182                CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
183                value.os.data=(unsigned char *)structure.desthost;
184                value.os.len=(size_t)strlen(structure.desthost);
185                CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
186                CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
187        }
188       
189       
190        //SIP Deregistration Reason (Grouped AVP)
191        {
192                CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Deregistration_Reason, 0, &groupedavp ) );
193               
194                //Reason Code
195                CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Code, 0, &avp ) );
196                value.i32=structure.reason;
197                CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
198                CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
199               
200                if(got_streason)
201                {
202                        //Reason Info
203                        CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Info, 0, &avp ) );
204                        value.os.data=(unsigned char *)structure.strreason;
205                        value.os.len=(size_t)strlen(structure.strreason);
206                        CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
207                        CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
208                }
209               
210                //We add the grouped AVP to the message
211                CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, groupedavp ) );
212        }
213       
214        //Username
215        {
216                if(got_username)
217                {
218                        CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) );
219                        value.os.data=(unsigned char *)structure.username;
220                        value.os.len=(size_t)strlen(structure.username);
221                        CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
222                        CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
223                }
224        }
225       
226        //SIP_AOR
227        {
228                if(num_aor>0)
229                {
230                        CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
231                        value.os.data=(unsigned char *)structure.sip_aor1;
232                        value.os.len=(size_t)strlen(structure.sip_aor1);
233                        CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
234                        CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
235                        if(num_aor>1)
236                        {
237                                CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
238                                value.os.data=(unsigned char *)structure.sip_aor2;
239                                value.os.len=(size_t)strlen(structure.sip_aor2);
240                                CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
241                                CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
242                                if(num_aor>2)
243                                {
244                                        CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
245                                        value.os.data=(unsigned char *)structure.sip_aor3;
246                                        value.os.len=(size_t)strlen(structure.sip_aor3);
247                                        CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
248                                        CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
249                                }
250                        }
251                }
252        }
253       
254        //TODO:remove for debug
255        //fd_msg_dump_walk(INFO,message);
256        CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
257       
258        return 0;
259}
260
261//Called when an RTA arrive
262int app_sip_RTA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
263{
264        //TODO: RTA reception
265/*
266        //TODO:remove unused variables
267        struct msg *ans, *qry;
268        struct avp *avp, *a2, *authdataitem;
269        struct msg_hdr * header = NULL;
270        struct avp_hdr * avphdr=NULL, *avpheader=NULL, *avpheader_auth=NULL,*digestheader=NULL;
271        union avp_value val;
272        int found_cnonce=0;
273        struct avp * tempavp=NULL,*sipAuthentication=NULL,*sipAuthenticate=NULL;
274        char * result;
275        int idx=0, idx2=0, number_of_auth_items=0,i=0;
276        //Flags and variables for Database
277        int sipurinotstored=0, authenticationpending=0, querylen=0, usernamelen=0;
278        char *query=NULL,*username=NULL;
279       
280       
281       
282        TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
283       
284        if (msg == NULL)
285                return EINVAL;
286       
287       
288        // Create answer header
289        qry = *msg;
290        CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
291        ans = *msg;     
292       
293       
294        // Add the Auth-Session-State AVP
295        {
296               
297                CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
298                CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
299               
300                CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
301                CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
302                CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
303        }
304       
305        CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Deregistration_Reason, &avp) );
306        CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
307       
308       
309       
310       
311       
312       
313       
314       
315       
316       
317       
318       
319       
320        */
321        return 0;
322       
323}
324
Note: See TracBrowser for help on using the repository browser.