jabberd2
2.2.17
Main Page
Data Structures
Files
File List
Globals
sm
sess.c
Go to the documentation of this file.
1
/*
2
* jabberd - Jabber Open Source Server
3
* Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4
* Ryan Eatmon, Robert Norris
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
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19
*/
20
21
#include "
sm.h
"
22
31
void
sess_route
(
sess_t
sess,
pkt_t
pkt) {
32
int
ns;
33
34
log_debug
(
ZONE
,
"routing pkt 0x%X to %s (%s) for %s"
, pkt, sess->
c2s
, sess->
c2s_id
,
jid_full
(sess->
jid
));
35
36
if
(pkt == NULL)
37
return
;
38
39
/* wrap it up */
40
ns =
nad_append_namespace
(pkt->
nad
, 1,
uri_SESSION
,
"sm"
);
41
42
nad_set_attr
(pkt->
nad
, 1, ns,
"c2s"
, sess->
c2s_id
, 0);
43
nad_set_attr
(pkt->
nad
, 1, ns,
"sm"
, sess->
sm_id
, 0);
44
45
nad_set_attr
(pkt->
nad
, 0, -1,
"to"
, sess->
c2s
, 0);
46
nad_set_attr
(pkt->
nad
, 0, -1,
"from"
, sess->
user
->
jid
->
domain
, 0);
47
48
/* remove error attribute */
49
nad_set_attr
(pkt->
nad
, 0, -1,
"error"
, NULL, 0);
50
51
/* and send it out */
52
sx_nad_write
(sess->
user
->
sm
->
router
, pkt->
nad
);
53
54
/* free up the packet */
55
if
(pkt->
rto
!= NULL)
jid_free
(pkt->
rto
);
56
if
(pkt->
rfrom
!= NULL)
jid_free
(pkt->
rfrom
);
57
if
(pkt->
to
!= NULL)
jid_free
(pkt->
to
);
58
if
(pkt->
from
!= NULL)
jid_free
(pkt->
from
);
59
free(pkt);
60
}
61
62
static
void
_sess_end_guts
(
sess_t
sess) {
63
sess_t
scan;
64
65
/* fake an unavailable presence from this session, so that modules and externals know we're gone */
66
if
(sess->
available
|| sess->
A
!= NULL)
67
mm_in_sess
(sess->
user
->
sm
->
mm
, sess,
pkt_create
(sess->
user
->
sm
,
"presence"
,
"unavailable"
, NULL, NULL));
68
69
/* inform the modules */
70
mm_sess_end
(sess->
user
->
sm
->
mm
, sess);
71
72
/* unlink it from this users sessions */
73
if
(sess->
user
->
sessions
== sess)
74
sess->
user
->
sessions
= sess->
next
;
75
else
{
76
for
(scan = sess->
user
->
sessions
; scan != NULL && scan->
next
!= sess; scan = scan->
next
);
77
if
(scan != NULL)
78
scan->
next
= sess->
next
;
79
}
80
81
/* and from global sessions */
82
xhash_zap
(sess->
user
->
sm
->
sessions
, sess->
sm_id
);
83
}
84
85
void
sess_end
(
sess_t
sess) {
86
log_debug
(
ZONE
,
"shutting down session %s"
,
jid_full
(sess->
jid
));
87
88
_sess_end_guts
(sess);
89
90
log_write
(sess->
user
->
sm
->
log
, LOG_NOTICE,
"session ended: jid=%s"
,
jid_full
(sess->
jid
));
91
92
/* if it was the last session, free the user */
93
if
(sess->
user
->
sessions
== NULL) {
94
mm_user_unload
(sess->
user
->
sm
->
mm
, sess->
user
);
95
log_write
(sess->
user
->
sm
->
log
, LOG_NOTICE,
"user unloaded jid=%s"
,
jid_user
(sess->
jid
));
96
user_free
(sess->
user
);
97
}
98
99
/* free the session */
100
pool_free
(sess->
p
);
101
}
102
103
sess_t
sess_start
(
sm_t
sm
,
jid_t
jid) {
104
pool_t
p;
105
user_t
user;
106
sess_t
sess, scan;
107
sha1_state_t
sha1;
108
char
hash[20];
109
int
replaced = 0;
110
111
log_debug
(
ZONE
,
"session requested for %s"
,
jid_full
(jid));
112
113
/* check whether it is to serviced domain */
114
if
(
xhash_get
(sm->
hosts
, jid->
domain
) == NULL) {
115
log_write
(sm->
log
, LOG_ERR,
"request to start session in non-serviced domain: jid=%s"
,
jid_full
(jid));
116
return
NULL;
117
}
118
119
/* get user data for this guy */
120
user =
user_load
(sm, jid);
121
122
/* unknown user */
123
if
(user == NULL) {
124
if
(
config_get
(sm->
config
,
"user.auto-create"
) == NULL) {
125
log_write
(sm->
log
, LOG_NOTICE,
"user not found and user.auto-create not enabled, can't start session: jid=%s"
,
jid_full
(jid));
126
return
NULL;
127
}
128
129
log_debug
(
ZONE
,
"auto-creating user %s"
,
jid_user
(jid));
130
131
if
(
user_create
(sm, jid) != 0)
132
return
NULL;
133
134
user =
user_load
(sm, jid);
135
if
(user == NULL) {
136
log_write
(sm->
log
, LOG_NOTICE,
"couldn't load user, can't start session: jid=%s"
,
jid_full
(jid));
137
return
NULL;
138
}
139
}
140
141
/* kill their old session if they have one */
142
for
(scan = user->
sessions
; scan != NULL; scan = scan->
next
)
143
if
(
jid_compare_full
(scan->
jid
, jid) == 0) {
144
log_debug
(
ZONE
,
"replacing session %s (%s)"
,
jid_full
(jid), scan->
c2s_id
);
145
146
/* !!! this "replaced" stuff is a hack - its really a subaction of "ended".
147
* hurrah, another control protocol rewrite is needed :(
148
*/
149
sm_c2s_action
(scan,
"replaced"
, NULL);
150
151
_sess_end_guts
(scan);
152
153
pool_free
(scan->
p
);
154
155
replaced = 1;
156
157
break
;
158
}
159
160
/* make a new session */
161
p =
pool_new
();
162
163
sess = (
sess_t
)
pmalloco
(p,
sizeof
(
struct
sess_st
));
164
sess->
p
= p;
165
166
/* fill it out */
167
sess->
pri
= 0;
168
sess->
user
= user;
169
170
sess->
jid
=
jid_dup
(jid);
171
pool_cleanup
(sess->
p
, (void (*))(
void
*)
jid_free
, sess->
jid
);
172
173
/* a place for modules to store stuff */
174
sess->
module_data
= (
void
**)
pmalloco
(sess->
p
,
sizeof
(
void
*) * sess->
user
->
sm
->
mm
->
nindex
);
175
176
/* add it to the list */
177
sess->
next
= user->
sessions
;
178
user->
sessions
= sess;
179
180
/* who c2s should address things to */
181
sha1_init
(&sha1);
182
datetime_out
(time(NULL),
dt_DATETIME
, sess->
sm_id
, 41);
183
sha1_append
(&sha1, sess->
sm_id
, strlen(sess->
sm_id
));
184
sha1_append
(&sha1,
jid_full
(sess->
jid
), strlen(
jid_full
(sess->
jid
)));
185
sha1_finish
(&sha1, hash);
186
hex_from_raw
(hash, 20, sess->
sm_id
);
187
188
log_debug
(
ZONE
,
"smid is %s"
, sess->
sm_id
);
189
190
/* remember it */
191
xhash_put
(sm->
sessions
, sess->
sm_id
, sess);
192
193
/* inform the modules */
194
/* !!! catch the return value - if its 1, don't let them in */
195
mm_sess_start
(sm->
mm
, sess);
196
197
if
(replaced)
198
log_write
(sm->
log
, LOG_NOTICE,
"session replaced: jid=%s"
,
jid_full
(sess->
jid
));
199
else
200
log_write
(sm->
log
, LOG_NOTICE,
"session started: jid=%s"
,
jid_full
(sess->
jid
));
201
202
return
sess;
203
}
204
206
sess_t
sess_match
(
user_t
user,
char
*resource) {
207
sess_t
sess;
208
209
for
(sess = user->
sessions
; sess != NULL; sess = sess->
next
) {
210
/* exact matches */
211
if
(strcmp(sess->
jid
->
resource
, resource) == 0)
212
return
sess;
213
}
214
215
return
NULL;
216
}
Generated by
1.8.1.1