Mercurial > pidgin
comparison src/protocols/oscar/conn.c @ 2270:d82efea341ef
[gaim-migrate @ 2280]
new libfaim. stupid bugs.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Wed, 12 Sep 2001 00:39:51 +0000 |
parents | 933346315b9b |
children | 8c75e59e4bdf |
comparison
equal
deleted
inserted
replaced
2269:7ff6170d84a0 | 2270:d82efea341ef |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * aim_conn.c | 3 * conn.c |
4 * | 4 * |
5 * Does all this gloriously nifty connection handling stuff... | 5 * Does all this gloriously nifty connection handling stuff... |
6 * | 6 * |
7 */ | 7 */ |
8 | 8 |
12 #ifndef _WIN32 | 12 #ifndef _WIN32 |
13 #include <netdb.h> | 13 #include <netdb.h> |
14 #include <sys/socket.h> | 14 #include <sys/socket.h> |
15 #include <netinet/in.h> | 15 #include <netinet/in.h> |
16 #endif | 16 #endif |
17 | |
18 /* | |
19 * In OSCAR, every connection has a set of SNAC groups associated | |
20 * with it. These are the groups that you can send over this connection | |
21 * without being guarenteed a "Not supported" SNAC error. | |
22 * | |
23 * The grand theory of things says that these associations transcend | |
24 * what libfaim calls "connection types" (conn->type). You can probably | |
25 * see the elegance here, but since I want to revel in it for a bit, you | |
26 * get to hear it all spelled out. | |
27 * | |
28 * So let us say that you have your core BOS connection running. One | |
29 * of your modules has just given you a SNAC of the group 0x0004 to send | |
30 * you. Maybe an IM destined for some twit in Greenland. So you start | |
31 * at the top of your connection list, looking for a connection that | |
32 * claims to support group 0x0004. You find one. Why, that neat BOS | |
33 * connection of yours can do that. So you send it on its way. | |
34 * | |
35 * Now, say, that fellow from Greenland has friends and they all want to | |
36 * meet up with you in a lame chat room. This has landed you a SNAC | |
37 * in the family 0x000e and you have to admit you're a bit lost. You've | |
38 * searched your connection list for someone who wants to make your life | |
39 * easy and deliver this SNAC for you, but there isn't one there. | |
40 * | |
41 * Here comes the good bit. Without even letting anyone know, particularly | |
42 * the module that decided to send this SNAC, and definitly not that twit | |
43 * in Greenland, you send out a service request. In this request, you have | |
44 * marked the need for a connection supporting group 0x000e. A few seconds | |
45 * later, you receive a service redirect with an IP address and a cookie in | |
46 * it. Great, you say. Now I have something to do. Off you go, making | |
47 * that connection. One of the first things you get from this new server | |
48 * is a message saying that indeed it does support the group you were looking | |
49 * for. So you continue and send rate confirmation and all that. | |
50 * | |
51 * Then you remember you had that SNAC to send, and now you have a means to | |
52 * do it, and you do, and everyone is happy. Except the Greenlander, who is | |
53 * still stuck in the bitter cold. | |
54 * | |
55 * Oh, and this is useful for building the Migration SNACs, too. In the | |
56 * future, this may help convince me to implement rate limit mitigation | |
57 * for real. We'll see. | |
58 * | |
59 * Just to make me look better, I'll say that I've known about this great | |
60 * scheme for quite some time now. But I still haven't convinced myself | |
61 * to make libfaim work that way. It would take a fair amount of effort, | |
62 * and probably some client API changes as well. (Whenever I don't want | |
63 * to do something, I just say it would change the client API. Then I | |
64 * instantly have a couple of supporters of not doing it.) | |
65 * | |
66 * Generally, addgroup is only called by the internal handling of the | |
67 * server ready SNAC. So if you want to do something before that, you'll | |
68 * have to be more creative. That is done rather early, though, so I don't | |
69 * think you have to worry about it. Unless you're me. I care deeply | |
70 * about such inane things. | |
71 * | |
72 */ | |
73 faim_internal void aim_conn_addgroup(aim_conn_t *conn, fu16_t group) | |
74 { | |
75 aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside; | |
76 struct snacgroup *sg; | |
77 | |
78 if (!(sg = malloc(sizeof(struct snacgroup)))) | |
79 return; | |
80 | |
81 faimdprintf(aim_conn_getsess(conn), 1, "adding group 0x%04x\n", group); | |
82 sg->group = group; | |
83 | |
84 sg->next = ins->groups; | |
85 ins->groups = sg; | |
86 | |
87 return; | |
88 } | |
89 | |
90 faim_export aim_conn_t *aim_conn_findbygroup(aim_session_t *sess, fu16_t group) | |
91 { | |
92 aim_conn_t *cur; | |
93 | |
94 for (cur = sess->connlist; cur; cur = cur->next) { | |
95 aim_conn_inside_t *ins = (aim_conn_inside_t *)cur->inside; | |
96 struct snacgroup *sg; | |
97 | |
98 for (sg = ins->groups; sg; sg = sg->next) { | |
99 if (sg->group == group) | |
100 return cur; | |
101 } | |
102 } | |
103 | |
104 return NULL; | |
105 } | |
106 | |
107 static struct snacgroup *connkill_snacgroups(struct snacgroup *sg) | |
108 { | |
109 | |
110 while (sg) { | |
111 struct snacgroup *tmp; | |
112 | |
113 tmp = sg->next; | |
114 free(sg); | |
115 sg = tmp; | |
116 } | |
117 | |
118 return NULL; | |
119 } | |
17 | 120 |
18 static void connkill_real(aim_session_t *sess, aim_conn_t **deadconn) | 121 static void connkill_real(aim_session_t *sess, aim_conn_t **deadconn) |
19 { | 122 { |
20 | 123 |
21 aim_rxqueue_cleanbyconn(sess, *deadconn); | 124 aim_rxqueue_cleanbyconn(sess, *deadconn); |
36 * This will free ->internal if it necessary... | 139 * This will free ->internal if it necessary... |
37 */ | 140 */ |
38 if ((*deadconn)->type == AIM_CONN_TYPE_RENDEZVOUS) | 141 if ((*deadconn)->type == AIM_CONN_TYPE_RENDEZVOUS) |
39 aim_conn_kill_rend(sess, *deadconn); | 142 aim_conn_kill_rend(sess, *deadconn); |
40 | 143 |
144 if ((*deadconn)->inside) { | |
145 aim_conn_inside_t *inside = (aim_conn_inside_t *)(*deadconn)->inside; | |
146 | |
147 inside->groups = connkill_snacgroups(inside->groups); | |
148 | |
149 free(inside); | |
150 } | |
151 | |
41 free(*deadconn); | 152 free(*deadconn); |
42 deadconn = NULL; | 153 deadconn = NULL; |
43 | 154 |
44 return; | 155 return; |
45 } | 156 } |
51 * Clears out the connection list and kills any connections left. | 162 * Clears out the connection list and kills any connections left. |
52 * | 163 * |
53 */ | 164 */ |
54 static void aim_connrst(aim_session_t *sess) | 165 static void aim_connrst(aim_session_t *sess) |
55 { | 166 { |
56 | |
57 faim_mutex_init(&sess->connlistlock); | |
58 | 167 |
59 if (sess->connlist) { | 168 if (sess->connlist) { |
60 aim_conn_t *cur = sess->connlist, *tmp; | 169 aim_conn_t *cur = sess->connlist, *tmp; |
61 | 170 |
62 while (cur) { | 171 while (cur) { |
91 deadconn->seqnum = 0; | 200 deadconn->seqnum = 0; |
92 deadconn->lastactivity = 0; | 201 deadconn->lastactivity = 0; |
93 deadconn->forcedlatency = 0; | 202 deadconn->forcedlatency = 0; |
94 deadconn->handlerlist = NULL; | 203 deadconn->handlerlist = NULL; |
95 deadconn->priv = NULL; | 204 deadconn->priv = NULL; |
96 faim_mutex_init(&deadconn->active); | 205 memset(deadconn->inside, 0, sizeof(aim_conn_inside_t)); |
97 faim_mutex_init(&deadconn->seqnum_lock); | |
98 | 206 |
99 return; | 207 return; |
100 } | 208 } |
101 | 209 |
102 /** | 210 /** |
111 aim_conn_t *newconn; | 219 aim_conn_t *newconn; |
112 | 220 |
113 if (!(newconn = malloc(sizeof(aim_conn_t)))) | 221 if (!(newconn = malloc(sizeof(aim_conn_t)))) |
114 return NULL; | 222 return NULL; |
115 memset(newconn, 0, sizeof(aim_conn_t)); | 223 memset(newconn, 0, sizeof(aim_conn_t)); |
224 | |
225 if (!(newconn->inside = malloc(sizeof(aim_conn_inside_t)))) { | |
226 free(newconn); | |
227 return NULL; | |
228 } | |
229 memset(newconn->inside, 0, sizeof(aim_conn_inside_t)); | |
116 | 230 |
117 aim_conn_init(newconn); | 231 aim_conn_init(newconn); |
118 | 232 |
119 newconn->next = sess->connlist; | 233 newconn->next = sess->connlist; |
120 sess->connlist = newconn; | 234 sess->connlist = newconn; |
166 * | 280 * |
167 */ | 281 */ |
168 faim_export void aim_conn_close(aim_conn_t *deadconn) | 282 faim_export void aim_conn_close(aim_conn_t *deadconn) |
169 { | 283 { |
170 | 284 |
171 faim_mutex_destroy(&deadconn->active); | |
172 faim_mutex_destroy(&deadconn->seqnum_lock); | |
173 if (deadconn->fd >= 3) | 285 if (deadconn->fd >= 3) |
174 close(deadconn->fd); | 286 close(deadconn->fd); |
175 deadconn->fd = -1; | 287 deadconn->fd = -1; |
176 if (deadconn->handlerlist) | 288 if (deadconn->handlerlist) |
177 aim_clearhandlers(deadconn); | 289 aim_clearhandlers(deadconn); |
178 if (deadconn->type == AIM_CONN_TYPE_RENDEZVOUS) | 290 if (deadconn->type == AIM_CONN_TYPE_RENDEZVOUS) |
179 aim_conn_close_rend((aim_session_t *)deadconn->sessv, deadconn); | 291 aim_conn_close_rend((aim_session_t *)deadconn->sessv, deadconn); |
180 | 292 |
181 | |
182 return; | 293 return; |
183 } | 294 } |
184 | 295 |
185 /** | 296 /** |
186 * aim_getconn_type - Find a connection of a specific type | 297 * aim_getconn_type - Find a connection of a specific type |
189 * | 300 * |
190 * Searches for a connection of the specified type in the | 301 * Searches for a connection of the specified type in the |
191 * specified session. Returns the first connection of that | 302 * specified session. Returns the first connection of that |
192 * type found. | 303 * type found. |
193 * | 304 * |
305 * XXX except for RENDEZVOUS, all uses of this should be removed and | |
306 * use aim_conn_findbygroup() instead. | |
194 */ | 307 */ |
195 faim_export aim_conn_t *aim_getconn_type(aim_session_t *sess, int type) | 308 faim_export aim_conn_t *aim_getconn_type(aim_session_t *sess, int type) |
196 { | 309 { |
197 aim_conn_t *cur; | 310 aim_conn_t *cur; |
198 | 311 |
199 faim_mutex_lock(&sess->connlistlock); | |
200 for (cur = sess->connlist; cur; cur = cur->next) { | 312 for (cur = sess->connlist; cur; cur = cur->next) { |
201 if ((cur->type == type) && | 313 if ((cur->type == type) && |
202 !(cur->status & AIM_CONN_STATUS_INPROGRESS)) | 314 !(cur->status & AIM_CONN_STATUS_INPROGRESS)) |
203 break; | 315 break; |
204 } | 316 } |
205 faim_mutex_unlock(&sess->connlistlock); | |
206 | 317 |
207 return cur; | 318 return cur; |
208 } | 319 } |
209 | 320 |
210 faim_export aim_conn_t *aim_getconn_type_all(aim_session_t *sess, int type) | 321 faim_export aim_conn_t *aim_getconn_type_all(aim_session_t *sess, int type) |
211 { | 322 { |
212 aim_conn_t *cur; | 323 aim_conn_t *cur; |
213 | 324 |
214 faim_mutex_lock(&sess->connlistlock); | |
215 for (cur = sess->connlist; cur; cur = cur->next) { | 325 for (cur = sess->connlist; cur; cur = cur->next) { |
216 if (cur->type == type) | 326 if (cur->type == type) |
217 break; | 327 break; |
218 } | 328 } |
219 faim_mutex_unlock(&sess->connlistlock); | |
220 | 329 |
221 return cur; | 330 return cur; |
222 } | 331 } |
223 | 332 |
224 /* If you pass -1 for the fd, you'll get what you ask for. Gibberish. */ | 333 /* If you pass -1 for the fd, you'll get what you ask for. Gibberish. */ |
225 faim_export aim_conn_t *aim_getconn_fd(aim_session_t *sess, int fd) | 334 faim_export aim_conn_t *aim_getconn_fd(aim_session_t *sess, int fd) |
226 { | 335 { |
227 aim_conn_t *cur; | 336 aim_conn_t *cur; |
228 | 337 |
229 faim_mutex_lock(&sess->connlistlock); | |
230 for (cur = sess->connlist; cur; cur = cur->next) { | 338 for (cur = sess->connlist; cur; cur = cur->next) { |
231 if (cur->fd == fd) | 339 if (cur->fd == fd) |
232 break; | 340 break; |
233 } | 341 } |
234 faim_mutex_unlock(&sess->connlistlock); | |
235 | 342 |
236 return cur; | 343 return cur; |
237 } | 344 } |
238 | 345 |
239 /** | 346 /** |
423 aim_conn_t *conn; | 530 aim_conn_t *conn; |
424 | 531 |
425 if (!(conn = aim_conn_getnext(sess))) | 532 if (!(conn = aim_conn_getnext(sess))) |
426 return NULL; | 533 return NULL; |
427 | 534 |
428 faim_mutex_lock(&conn->active); | |
429 | |
430 conn->fd = src->fd; | 535 conn->fd = src->fd; |
431 conn->type = src->type; | 536 conn->type = src->type; |
432 conn->subtype = src->subtype; | 537 conn->subtype = src->subtype; |
433 conn->seqnum = src->seqnum; | 538 conn->seqnum = src->seqnum; |
434 conn->priv = src->priv; | 539 conn->priv = src->priv; |
436 conn->lastactivity = src->lastactivity; | 541 conn->lastactivity = src->lastactivity; |
437 conn->forcedlatency = src->forcedlatency; | 542 conn->forcedlatency = src->forcedlatency; |
438 conn->sessv = src->sessv; | 543 conn->sessv = src->sessv; |
439 aim_clonehandlers(sess, conn, src); | 544 aim_clonehandlers(sess, conn, src); |
440 | 545 |
441 faim_mutex_unlock(&conn->active); | 546 if (src->inside) { |
547 /* | |
548 * XXX should clone this section as well, but since currently | |
549 * this function only gets called for some of that rendezvous | |
550 * crap, and not on SNAC connections, its probably okay for | |
551 * now. | |
552 * | |
553 */ | |
554 } | |
442 | 555 |
443 return conn; | 556 return conn; |
444 } | 557 } |
445 | 558 |
446 /** | 559 /** |
465 int i, ret; | 578 int i, ret; |
466 | 579 |
467 if (!(connstruct = aim_conn_getnext(sess))) | 580 if (!(connstruct = aim_conn_getnext(sess))) |
468 return NULL; | 581 return NULL; |
469 | 582 |
470 faim_mutex_lock(&connstruct->active); | |
471 | |
472 connstruct->sessv = (void *)sess; | 583 connstruct->sessv = (void *)sess; |
473 connstruct->type = type; | 584 connstruct->type = type; |
474 | 585 |
475 if (!dest) { /* just allocate a struct */ | 586 if (!dest) { /* just allocate a struct */ |
476 connstruct->fd = -1; | 587 connstruct->fd = -1; |
477 connstruct->status = 0; | 588 connstruct->status = 0; |
478 faim_mutex_unlock(&connstruct->active); | |
479 return connstruct; | 589 return connstruct; |
480 } | 590 } |
481 | 591 |
482 /* | 592 /* |
483 * As of 23 Jul 1999, AOL now sends the port number, preceded by a | 593 * As of 23 Jul 1999, AOL now sends the port number, preceded by a |
501 | 611 |
502 if ((ret = aim_proxyconnect(sess, host, port, &connstruct->status)) < 0) { | 612 if ((ret = aim_proxyconnect(sess, host, port, &connstruct->status)) < 0) { |
503 connstruct->fd = -1; | 613 connstruct->fd = -1; |
504 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); | 614 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); |
505 free(host); | 615 free(host); |
506 faim_mutex_unlock(&connstruct->active); | |
507 return connstruct; | 616 return connstruct; |
508 } else | 617 } else |
509 connstruct->fd = ret; | 618 connstruct->fd = ret; |
510 | 619 |
511 faim_mutex_unlock(&connstruct->active); | |
512 | |
513 free(host); | 620 free(host); |
514 | 621 |
515 return connstruct; | 622 return connstruct; |
516 } | 623 } |
517 | 624 |
526 faim_export int aim_conngetmaxfd(aim_session_t *sess) | 633 faim_export int aim_conngetmaxfd(aim_session_t *sess) |
527 { | 634 { |
528 int j; | 635 int j; |
529 aim_conn_t *cur; | 636 aim_conn_t *cur; |
530 | 637 |
531 faim_mutex_lock(&sess->connlistlock); | |
532 for (cur = sess->connlist, j = 0; cur; cur = cur->next) { | 638 for (cur = sess->connlist, j = 0; cur; cur = cur->next) { |
533 if (cur->fd > j) | 639 if (cur->fd > j) |
534 j = cur->fd; | 640 j = cur->fd; |
535 } | 641 } |
536 faim_mutex_unlock(&sess->connlistlock); | |
537 | 642 |
538 return j; | 643 return j; |
539 } | 644 } |
540 | 645 |
541 /** | 646 /** |
549 */ | 654 */ |
550 faim_export int aim_conn_in_sess(aim_session_t *sess, aim_conn_t *conn) | 655 faim_export int aim_conn_in_sess(aim_session_t *sess, aim_conn_t *conn) |
551 { | 656 { |
552 aim_conn_t *cur; | 657 aim_conn_t *cur; |
553 | 658 |
554 faim_mutex_lock(&sess->connlistlock); | |
555 for (cur = sess->connlist; cur; cur = cur->next) { | 659 for (cur = sess->connlist; cur; cur = cur->next) { |
556 if (cur == conn) { | 660 if (cur == conn) |
557 faim_mutex_unlock(&sess->connlistlock); | |
558 return 1; | 661 return 1; |
559 } | 662 } |
560 } | |
561 faim_mutex_unlock(&sess->connlistlock); | |
562 | 663 |
563 return 0; | 664 return 0; |
564 } | 665 } |
565 | 666 |
566 /** | 667 /** |
576 * -1 error in select() (%NULL returned) | 677 * -1 error in select() (%NULL returned) |
577 * 0 no events pending (%NULL returned) | 678 * 0 no events pending (%NULL returned) |
578 * 1 outgoing data pending (%NULL returned) | 679 * 1 outgoing data pending (%NULL returned) |
579 * 2 incoming data pending (connection with pending data returned) | 680 * 2 incoming data pending (connection with pending data returned) |
580 * | 681 * |
581 * XXX: we could probably stand to do a little courser locking here. | |
582 * | |
583 */ | 682 */ |
584 faim_export aim_conn_t *aim_select(aim_session_t *sess, struct timeval *timeout, int *status) | 683 faim_export aim_conn_t *aim_select(aim_session_t *sess, struct timeval *timeout, int *status) |
585 { | 684 { |
586 aim_conn_t *cur; | 685 aim_conn_t *cur; |
587 fd_set fds, wfds; | 686 fd_set fds, wfds; |
588 int maxfd, i, haveconnecting = 0; | 687 int maxfd, i, haveconnecting = 0; |
589 | 688 |
590 faim_mutex_lock(&sess->connlistlock); | |
591 if (!sess->connlist) { | 689 if (!sess->connlist) { |
592 faim_mutex_unlock(&sess->connlistlock); | |
593 *status = -1; | 690 *status = -1; |
594 return NULL; | 691 return NULL; |
595 } | 692 } |
596 faim_mutex_unlock(&sess->connlistlock); | |
597 | 693 |
598 FD_ZERO(&fds); | 694 FD_ZERO(&fds); |
599 FD_ZERO(&wfds); | 695 FD_ZERO(&wfds); |
600 | 696 |
601 faim_mutex_lock(&sess->connlistlock); | |
602 for (cur = sess->connlist, maxfd = 0; cur; cur = cur->next) { | 697 for (cur = sess->connlist, maxfd = 0; cur; cur = cur->next) { |
603 if (cur->fd == -1) { | 698 if (cur->fd == -1) { |
604 /* don't let invalid/dead connections sit around */ | 699 /* don't let invalid/dead connections sit around */ |
605 *status = 2; | 700 *status = 2; |
606 faim_mutex_unlock(&sess->connlistlock); | |
607 return cur; | 701 return cur; |
608 } else if (cur->status & AIM_CONN_STATUS_INPROGRESS) { | 702 } else if (cur->status & AIM_CONN_STATUS_INPROGRESS) { |
609 FD_SET(cur->fd, &wfds); | 703 FD_SET(cur->fd, &wfds); |
610 | 704 |
611 haveconnecting++; | 705 haveconnecting++; |
612 } | 706 } |
613 FD_SET(cur->fd, &fds); | 707 FD_SET(cur->fd, &fds); |
614 if (cur->fd > maxfd) | 708 if (cur->fd > maxfd) |
615 maxfd = cur->fd; | 709 maxfd = cur->fd; |
616 } | 710 } |
617 faim_mutex_unlock(&sess->connlistlock); | |
618 | 711 |
619 /* | 712 /* |
620 * If we have data waiting to be sent, return | 713 * If we have data waiting to be sent, return |
621 * | 714 * |
622 * We have to not do this if theres at least one | 715 * We have to not do this if theres at least one |
634 *status = 1; | 727 *status = 1; |
635 return NULL; | 728 return NULL; |
636 } | 729 } |
637 | 730 |
638 if ((i = select(maxfd+1, &fds, &wfds, NULL, timeout))>=1) { | 731 if ((i = select(maxfd+1, &fds, &wfds, NULL, timeout))>=1) { |
639 faim_mutex_lock(&sess->connlistlock); | |
640 for (cur = sess->connlist; cur; cur = cur->next) { | 732 for (cur = sess->connlist; cur; cur = cur->next) { |
641 if ((FD_ISSET(cur->fd, &fds)) || | 733 if ((FD_ISSET(cur->fd, &fds)) || |
642 ((cur->status & AIM_CONN_STATUS_INPROGRESS) && | 734 ((cur->status & AIM_CONN_STATUS_INPROGRESS) && |
643 FD_ISSET(cur->fd, &wfds))) { | 735 FD_ISSET(cur->fd, &wfds))) { |
644 *status = 2; | 736 *status = 2; |
645 faim_mutex_unlock(&sess->connlistlock); | 737 return cur; |
646 return cur; /* XXX race condition here -- shouldnt unlock connlist */ | |
647 } | 738 } |
648 } | 739 } |
649 *status = 0; /* shouldn't happen */ | 740 *status = 0; /* shouldn't happen */ |
650 } else if ((i == -1) && (errno == EINTR)) /* treat interrupts as a timeout */ | 741 } else if ((i == -1) && (errno == EINTR)) /* treat interrupts as a timeout */ |
651 *status = 0; | 742 *status = 0; |
652 else | 743 else |
653 *status = i; /* can be 0 or -1 */ | 744 *status = i; /* can be 0 or -1 */ |
654 | 745 |
655 faim_mutex_unlock(&sess->connlistlock); | |
656 | |
657 return NULL; /* no waiting or error, return */ | 746 return NULL; /* no waiting or error, return */ |
658 } | 747 } |
659 | 748 |
660 /** | 749 /** |
661 * aim_conn_setlatency - Set a forced latency value for connection | 750 * aim_conn_setlatency - Set a forced latency value for connection |
675 { | 764 { |
676 | 765 |
677 if (!conn) | 766 if (!conn) |
678 return -1; | 767 return -1; |
679 | 768 |
680 faim_mutex_lock(&conn->active); | |
681 conn->forcedlatency = newval; | 769 conn->forcedlatency = newval; |
682 conn->lastactivity = 0; /* reset this just to make sure */ | 770 conn->lastactivity = 0; /* reset this just to make sure */ |
683 faim_mutex_unlock(&conn->active); | |
684 | 771 |
685 return 0; | 772 return 0; |
686 } | 773 } |
687 | 774 |
688 /** | 775 /** |