comparison freeDiameter/sctps.c @ 209:b9f48f2f2a22

Some cleanups in the code
author Sebastien Decugis <sdecugis@nict.go.jp>
date Tue, 16 Feb 2010 15:29:55 +0900
parents a68d24defda8
children 5a1b93f59f8f
comparison
equal deleted inserted replaced
208:e1da03ba112f 209:b9f48f2f2a22
84 ASSERT( conn->cc_proto == IPPROTO_SCTP ); 84 ASSERT( conn->cc_proto == IPPROTO_SCTP );
85 ASSERT( Target_Queue(conn) ); 85 ASSERT( Target_Queue(conn) );
86 ASSERT( conn->cc_sctps_data.array ); 86 ASSERT( conn->cc_sctps_data.array );
87 87
88 do { 88 do {
89 CHECK_FCT_DO( fd_sctp_recvmeta(conn->cc_socket, &strid, &buf, &bufsz, &event, &conn->cc_closing), goto error ); 89 CHECK_FCT_DO( fd_sctp_recvmeta(conn->cc_socket, &strid, &buf, &bufsz, &event, &conn->cc_status), goto fatal );
90 switch (event) { 90 switch (event) {
91 case FDEVP_CNX_MSG_RECV: 91 case FDEVP_CNX_MSG_RECV:
92 /* Demux this message in the appropriate fifo, another thread will pull, gnutls process, and send in target queue */ 92 /* Demux this message to the appropriate fifo, another thread will pull, gnutls process, and send to target queue */
93 if (strid < conn->cc_sctp_para.pairs) { 93 if (strid < conn->cc_sctp_para.pairs) {
94 CHECK_FCT_DO(fd_event_send(conn->cc_sctps_data.array[strid].raw_recv, event, bufsz, buf), goto error ); 94 CHECK_FCT_DO(fd_event_send(conn->cc_sctps_data.array[strid].raw_recv, event, bufsz, buf), goto fatal );
95 } else { 95 } else {
96 TRACE_DEBUG(INFO, "Received packet (%d bytes) on out-of-range stream #%s from %s, discarded.", bufsz, strid, conn->cc_remid); 96 TRACE_DEBUG(INFO, "Received packet (%d bytes) on out-of-range stream #%s from %s, discarded.", bufsz, strid, conn->cc_remid);
97 free(buf); 97 free(buf);
98 } 98 }
99 break; 99 break;
100 100
101 case FDEVP_CNX_EP_CHANGE: 101 case FDEVP_CNX_EP_CHANGE:
102 /* Send this event to the target queue */ 102 /* Send this event to the target queue */
103 CHECK_FCT_DO( fd_event_send( Target_Queue(conn), event, bufsz, buf), goto error ); 103 CHECK_FCT_DO( fd_event_send( Target_Queue(conn), event, bufsz, buf), goto fatal );
104 break; 104 break;
105 105
106 case FDEVP_CNX_ERROR: 106 case FDEVP_CNX_ERROR:
107 fd_cnx_markerror(conn);
108 goto out;
109
107 default: 110 default:
108 goto error; 111 goto fatal;
109 } 112 }
110 113
111 } while (conn->cc_loop); 114 } while (conn->cc_loop);
112 115
113 out: 116 out:
114 TRACE_DEBUG(FULL, "Thread terminated"); 117 TRACE_DEBUG(FULL, "Thread terminated");
115 return NULL; 118 return NULL;
116 error: 119
117 if (!conn->cc_closing) { 120 fatal:
118 CHECK_FCT_DO( fd_event_send( Target_Queue(conn), FDEVP_CNX_ERROR, 0, NULL), /* continue or destroy everything? */); 121 /* An unrecoverable error occurred, stop the daemon */
119 } 122 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), );
120
121 goto out; 123 goto out;
122 } 124 }
123 125
124 /* Decrypt the data received in this stream pair and store it in the target queue */ 126 /* Decrypt the data received in this stream pair and store it in the target queue */
125 static void * decipher(void * arg) 127 static void * decipher(void * arg)
137 char buf[48]; 139 char buf[48];
138 snprintf(buf, sizeof(buf), "Decipher (%hu@%d)", ctx->strid, cnx->cc_socket); 140 snprintf(buf, sizeof(buf), "Decipher (%hu@%d)", ctx->strid, cnx->cc_socket);
139 fd_log_threadname ( buf ); 141 fd_log_threadname ( buf );
140 } 142 }
141 143
144 /* The next function loops while there is no error */
142 CHECK_FCT_DO(fd_tls_rcvthr_core(cnx, ctx->strid ? ctx->session : cnx->cc_tls_para.session), /* continue */); 145 CHECK_FCT_DO(fd_tls_rcvthr_core(cnx, ctx->strid ? ctx->session : cnx->cc_tls_para.session), /* continue */);
143 error: 146 error:
144 if (!cnx->cc_closing) { 147 fd_cnx_markerror(cnx);
145 CHECK_FCT_DO( fd_event_send( Target_Queue(cnx), FDEVP_CNX_ERROR, 0, NULL), /* continue or destroy everything? */);
146 }
147 TRACE_DEBUG(FULL, "Thread terminated"); 148 TRACE_DEBUG(FULL, "Thread terminated");
148 return NULL; 149 return NULL;
149 } 150 }
150 151
151 /*************************************************************/ 152 /*************************************************************/
158 struct sctps_ctx * ctx = (struct sctps_ctx *) tr; 159 struct sctps_ctx * ctx = (struct sctps_ctx *) tr;
159 160
160 TRACE_ENTRY("%p %p %zd", tr, data, len); 161 TRACE_ENTRY("%p %p %zd", tr, data, len);
161 CHECK_PARAMS_DO( tr && data, { errno = EINVAL; return -1; } ); 162 CHECK_PARAMS_DO( tr && data, { errno = EINVAL; return -1; } );
162 163
163 CHECK_FCT_DO( fd_sctp_sendstr(ctx->parent->cc_socket, ctx->strid, (uint8_t *)data, len, &ctx->parent->cc_closing), /* errno is already set */ return -1 ); 164 CHECK_FCT_DO( fd_sctp_sendstr(ctx->parent->cc_socket, ctx->strid, (uint8_t *)data, len, &ctx->parent->cc_status), /* errno is already set */ return -1 );
164 165
165 return len; 166 return len;
166 } 167 }
167 168
168 /* Retrieve data received on a stream and already demultiplexed */ 169 /* Retrieve data received on a stream and already demultiplexed */
173 int emptied; 174 int emptied;
174 175
175 TRACE_ENTRY("%p %p %zd", tr, buf, len); 176 TRACE_ENTRY("%p %p %zd", tr, buf, len);
176 CHECK_PARAMS_DO( tr && buf, { errno = EINVAL; return -1; } ); 177 CHECK_PARAMS_DO( tr && buf, { errno = EINVAL; return -1; } );
177 178
178 /* If we don't have data available now, pull new message from the fifo -- this is blocking */ 179 /* If we don't have data available now, pull new message from the fifo -- this is blocking (until the queue is destroyed) */
179 if (!ctx->partial.buf) { 180 if (!ctx->partial.buf) {
180 int ev; 181 int ev;
181 CHECK_FCT_DO( errno = fd_event_get(ctx->raw_recv, &ev, &ctx->partial.bufsz, (void *)&ctx->partial.buf), return -1 ); 182 CHECK_FCT_DO( errno = fd_event_get(ctx->raw_recv, &ev, &ctx->partial.bufsz, (void *)&ctx->partial.buf), return -1 );
182 ASSERT( ev == FDEVP_CNX_MSG_RECV ); 183 ASSERT( ev == FDEVP_CNX_MSG_RECV );
183 } 184 }
228 229
229 struct sr_store { 230 struct sr_store {
230 struct fd_list list; /* list of sr_data, ordered by key.size then key.data */ 231 struct fd_list list; /* list of sr_data, ordered by key.size then key.data */
231 pthread_rwlock_t lock; 232 pthread_rwlock_t lock;
232 struct cnxctx *parent; 233 struct cnxctx *parent;
233 /* Add another list to chain in a global list to implement a garbage collector on sessions */ 234 /* Add another list to chain in a global list to implement a garbage collector on sessions -- TODO */
234 }; 235 };
235 236
236 /* Saved master session data for resuming sessions */ 237 /* Saved master session data for resuming sessions */
237 struct sr_data { 238 struct sr_data {
238 struct fd_list chain; 239 struct fd_list chain;
333 if (match) { 334 if (match) {
334 sr = (struct sr_data *)li; 335 sr = (struct sr_data *)li;
335 336
336 /* Check the data is the same */ 337 /* Check the data is the same */
337 if ((data.size != sr->data.size) || memcmp(data.data, sr->data.data, data.size)) { 338 if ((data.size != sr->data.size) || memcmp(data.data, sr->data.data, data.size)) {
338 TRACE_DEBUG(SR_LEVEL, "GnuTLS tried to store a session with same key and different data!"); 339 TRACE_DEBUG(INFO, "GnuTLS tried to store a session with same key and different data!");
339 ret = -1; 340 ret = -1;
340 } else { 341 } else {
341 TRACE_DEBUG(SR_LEVEL, "GnuTLS tried to store a session with same key and same data, skipped."); 342 TRACE_DEBUG(SR_LEVEL, "GnuTLS tried to store a session with same key and same data, skipped.");
342 } 343 }
343 goto out; 344 goto out;
568 if (ret == NULL) { 569 if (ret == NULL) {
569 errors++; /* Handshake failed on this stream */ 570 errors++; /* Handshake failed on this stream */
570 } 571 }
571 } 572 }
572 573
573 return errors ? ENOTCONN : 0; 574 if (errors) {
575 TRACE_DEBUG(INFO, "Handshake failed on %d/%hd stream pairs", errors, conn->cc_sctp_para.pairs);
576 fd_cnx_markerror(conn);
577 return ENOTCONN;
578 }
579
580 return 0;
574 } 581 }
575 582
576 /* Receive messages from all stream pairs */ 583 /* Receive messages from all stream pairs */
577 int fd_sctps_startthreads(struct cnxctx * conn) 584 int fd_sctps_startthreads(struct cnxctx * conn)
578 { 585 {
596 603
597 CHECK_PARAMS_DO( conn && conn->cc_sctps_data.array, return ); 604 CHECK_PARAMS_DO( conn && conn->cc_sctps_data.array, return );
598 605
599 /* End all TLS sessions, in series (not as efficient as paralel, but simpler) */ 606 /* End all TLS sessions, in series (not as efficient as paralel, but simpler) */
600 for (i = 1; i < conn->cc_sctp_para.pairs; i++) { 607 for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
601 CHECK_GNUTLS_DO( gnutls_bye(conn->cc_sctps_data.array[i].session, GNUTLS_SHUT_WR), /* Continue */ ); 608 if (!conn->cc_status & CC_STATUS_ERROR) {
609 CHECK_GNUTLS_DO( gnutls_bye(conn->cc_sctps_data.array[i].session, GNUTLS_SHUT_WR), fd_cnx_markerror(conn) );
610 }
602 } 611 }
603 } 612 }
604 613
605 /* After "bye" was sent on all streams, read from sessions until an error is received */ 614 /* After "bye" was sent on all streams, read from sessions until an error is received */
606 void fd_sctps_waitthreadsterm(struct cnxctx * conn) 615 void fd_sctps_waitthreadsterm(struct cnxctx * conn)
626 635
627 TRACE_ENTRY("%p", conn); 636 TRACE_ENTRY("%p", conn);
628 CHECK_PARAMS_DO( conn && conn->cc_sctps_data.array, return ); 637 CHECK_PARAMS_DO( conn && conn->cc_sctps_data.array, return );
629 638
630 for (i = 1; i < conn->cc_sctp_para.pairs; i++) { 639 for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
631 gnutls_deinit(conn->cc_sctps_data.array[i].session); 640 if (conn->cc_sctps_data.array[i].session) {
641 gnutls_deinit(conn->cc_sctps_data.array[i].session);
642 conn->cc_sctps_data.array[i].session = NULL;
643 }
632 } 644 }
633 } 645 }
634 646
635 647
636 /* Stop all receiver threads */ 648 /* Stop all receiver threads */
663 /* Free remaining data in the array */ 675 /* Free remaining data in the array */
664 for (i = 0; i < conn->cc_sctp_para.pairs; i++) { 676 for (i = 0; i < conn->cc_sctp_para.pairs; i++) {
665 if (conn->cc_sctps_data.array[i].raw_recv) 677 if (conn->cc_sctps_data.array[i].raw_recv)
666 fd_event_destroy( &conn->cc_sctps_data.array[i].raw_recv, free ); 678 fd_event_destroy( &conn->cc_sctps_data.array[i].raw_recv, free );
667 free(conn->cc_sctps_data.array[i].partial.buf); 679 free(conn->cc_sctps_data.array[i].partial.buf);
668 /* gnutls_session was already deinit */ 680 if (conn->cc_sctps_data.array[i].session) {
681 gnutls_deinit(conn->cc_sctps_data.array[i].session);
682 conn->cc_sctps_data.array[i].session = NULL;
683 }
669 } 684 }
670 685
671 /* Free the array itself now */ 686 /* Free the array itself now */
672 free(conn->cc_sctps_data.array); 687 free(conn->cc_sctps_data.array);
673 conn->cc_sctps_data.array = NULL; 688 conn->cc_sctps_data.array = NULL;
"Welcome to our mercurial repository"