Changeset 21:bef197f6826f in freeDiameter
- Timestamp:
- Oct 8, 2009, 8:05:16 PM (15 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/freediameter.conf.sample
r20 r21 214 214 ConnectPeer = "jules.nautilus6.org" ; 215 215 ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; No_TCP; SCTP_streams = 60; } ; 216 TLS_Cred = "/etc/openssl-ca/clients/certs/ fdtest.cert" , "/etc/openssl-ca/clients/privkeys/fdtest.key.pem";216 TLS_Cred = "/etc/openssl-ca/clients/certs/test.cert" , "/etc/openssl-ca/clients/privkeys/test.key.pem"; 217 217 TLS_CA = "/etc/openssl-ca/public-www/cacert.pem"; 218 218 # TLS_CRL = "/etc/openssl-ca/public-www/crl.pem"; -
freeDiameter/cnxctx.c
r20 r21 36 36 #include "fD.h" 37 37 38 /* Initialize a connection context */ 38 /* The connection context structure */ 39 struct cnxctx { 40 int cc_socket; /* The socket object of the connection -- <=0 if no socket is created */ 41 42 int cc_proto; /* IPPROTO_TCP or IPPROTO_SCTP */ 43 int cc_tls; /* Is TLS already started ? */ 44 45 struct fifo * cc_events; /* Events occuring on the connection */ 46 pthread_t cc_mgr; /* manager thread for the connection */ 47 struct fifo * cc_incoming; /* FIFO queue of messages received on the connection */ 48 49 uint16_t cc_port; /* Remote port of the connection, when we are client */ 50 struct fd_list cc_ep_remote; /* The remote address(es) of the connection */ 51 struct fd_list cc_ep_local; /* The local address(es) of the connection */ 52 53 /* If cc_proto == SCTP */ 54 struct { 55 int str_out;/* Out streams */ 56 int str_in; /* In streams */ 57 int pairs; /* max number of pairs ( = min(in, out)) */ 58 int next; /* # of stream the next message will be sent to */ 59 } cc_sctp_para; 60 61 /* If cc_tls == true */ 62 struct { 63 int mode; /* GNUTLS_CLIENT / GNUTLS_SERVER */ 64 gnutls_session_t session; /* Session object (stream #0 in case of SCTP) */ 65 } cc_tls_para; 66 67 /* If both conditions */ 68 struct { 69 gnutls_session_t *res_sessions; /* Sessions of other pairs of streams, resumed from the first */ 70 /* Buffers, threads, ... */ 71 } cc_sctp_tls_para; 72 }; 73 74 75 /* Initialize a context structure from a socket */ 39 76 struct cnxctx * fd_cnx_init(int sock, int proto) 40 77 { … … 66 103 } 67 104 68 /* TLS handshake the connection */ 105 /* Start receving messages in clear (no TLS) on the connection */ 106 int fd_cnx_start_clear(struct cnxctx * conn) 107 { 108 109 TODO("..."); 110 return ENOTSUP; 111 } 112 113 /* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */ 69 114 int fd_cnx_handshake(struct cnxctx * conn, int mode) 70 115 { … … 142 187 return 0; 143 188 } 189 190 /* Retrieve TLS credentials of the remote peer, after handshake */ 191 int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size) 192 { 193 194 TODO("..."); 195 return ENOTSUP; 196 } 197 198 /* Get the list of endpoints (IP addresses) of the remote peer on this object */ 199 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti) 200 { 201 202 TODO("..."); 203 return ENOTSUP; 204 } 205 206 207 /* Get a string describing the remote peer address (ip address or fqdn) */ 208 char * fd_cnx_getremoteid(struct cnxctx * conn) 209 { 210 211 TODO("..."); 212 return NULL; 213 } 214 215 216 /* Receive next message. if timeout is not NULL, wait only until timeout */ 217 int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len) 218 { 219 220 TODO("..."); 221 return ENOTSUP; 222 } 223 224 225 /* Send a message */ 226 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len) 227 { 228 229 TODO("..."); 230 return ENOTSUP; 231 } 232 233 234 /* Destroy a conn structure, and shutdown the socket */ 235 void fd_cnx_destroy(struct cnxctx * conn) 236 { 237 238 TODO("..."); 239 return; 240 } 241 242 243 244 -
freeDiameter/fD.h
r20 r21 173 173 }; 174 174 175 /* The connection context structure */176 struct cnxctx {177 int cc_socket; /* The socket object of the connection -- <=0 if no socket is created */178 179 struct fifo **cc_events; /* Location of the events list to send connection events */180 181 int cc_proto; /* IPPROTO_TCP or IPPROTO_SCTP */182 int cc_tls; /* Is TLS already started ? */183 184 uint16_t cc_port; /* Remote port of the connection, when we are client */185 struct fd_list cc_ep_remote; /* The remote address(es) of the connection */186 struct fd_list cc_ep_local; /* The local address(es) of the connection */187 188 /* If cc_proto == SCTP */189 struct {190 int str_out;/* Out streams */191 int str_in; /* In streams */192 int pairs; /* max number of pairs ( = min(in, out)) */193 int next; /* # of stream the next message will be sent to */194 } cc_sctp_para;195 196 /* If cc_tls == true */197 struct {198 int mode; /* GNUTLS_CLIENT / GNUTLS_SERVER */199 gnutls_session_t session; /* Session object (stream #0 in case of SCTP) */200 } cc_tls_para;201 202 /* If both conditions */203 struct {204 gnutls_session_t *res_sessions; /* Sessions of other pairs of streams, resumed from the first */205 /* Buffers, threads, ... */206 } cc_sctp_tls_para;207 };208 175 209 176 /* Functions */ … … 233 200 /* Connection contexts */ 234 201 struct cnxctx * fd_cnx_init(int sock, int proto); 202 int fd_cnx_start_clear(struct cnxctx * conn); 235 203 int fd_cnx_handshake(struct cnxctx * conn, int mode); 204 int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size); 205 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti); 206 char * fd_cnx_getremoteid(struct cnxctx * conn); 207 int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len); 208 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len); 209 void fd_cnx_destroy(struct cnxctx * conn); 236 210 237 211 /* SCTP */ -
freeDiameter/server.c
r20 r21 62 62 struct client { 63 63 struct fd_list chain; /* link in the server's list of clients */ 64 65 64 struct cnxctx *conn; /* Parameters of the connection; sends its events to the ev fifo bellow */ 66 67 65 struct timespec ts; /* Delay for receiving CER: INCNX_TIMEOUT */ 68 struct fifo *ev; /* Events of the connection -- allowed: TIMEOUT, ERROR (cnx, tls), MSG_RCV (CER, other=>error) */69 70 66 pthread_t cli_thr; /* connection state machine (simplified PSM) */ 71 67 }; … … 80 76 81 77 78 static void * client_simple_psm(void * arg) 79 { 80 struct client * c = arg; 81 struct server * s = NULL; 82 83 TRACE_ENTRY("%p", c); 84 85 CHECK_PARAMS_DO(c && c->conn && c->chain.head, goto fatal_error ); 86 87 s = c->chain.head->o; 88 89 /* Name the current thread */ 90 { 91 char addr[128]; 92 snprintf(addr, sizeof(addr), "Srv %d/Cli %s", s->socket, fd_cnx_getremoteid(c->conn)); 93 fd_log_threadname ( addr ); 94 } 95 96 /* Set the timeout to receive the first message */ 97 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &c->ts), goto fatal_error ); 98 c->ts.tv_sec += INCNX_TIMEOUT; 99 100 TODO("receive message until c->ts"); 101 102 TODO("Timeout => close"); 103 TODO("Message != CER => close"); 104 TODO("Message == CER : "); 105 TODO("Search matching peer"); 106 TODO("..."); 107 108 /* The end: we have freed the client structure already */ 109 TODO("Unlink the client structure"); 110 TODO(" pthread_detach(c->cli_thr); "); 111 TODO(" free(c); "); 112 return NULL; 113 114 fatal_error: /* This has effect to terminate the daemon */ 115 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), ); 116 return NULL; 117 } 118 82 119 /* This thread is called when a new client had just connected */ 83 120 static void * handle_client_fast(void * arg) … … 90 127 { 91 128 char addr[128]; 92 int offset = snprintf(addr, sizeof(addr), "Srv %d/Cli %d : ", cf->serv->socket, cf->sock);129 int offset = snprintf(addr, sizeof(addr), "Srv %d/CliFast %d : ", cf->serv->socket, cf->sock); 93 130 int rc = getnameinfo((sSA *)&cf->ss, sizeof(sSS), addr + offset, sizeof(addr) - offset, NULL, 0, 0); 94 131 if (rc) 95 132 memcpy(addr + offset, gai_strerror(rc), sizeof(addr) - offset); 96 133 134 fd_log_threadname ( addr ); 135 97 136 if (TRACE_BOOL(INFO)) { 98 137 fd_log_debug( "New connection %s, sock %d, from '%s'\n", cf->serv->serv_name, cf->sock, addr + offset); 99 138 } 100 101 fd_log_threadname ( addr );102 139 } 103 140 104 141 /* Create a client structure */ 105 CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto early_error );142 CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto fatal_error ); 106 143 memset(c, 0, sizeof(struct client)); 107 144 fd_list_init(&c->chain, c); 108 c->cli_thr = pthread_self();109 145 110 146 /* Create the connection context */ 111 CHECK_MALLOC_DO( c->conn = fd_cnx_init(cf->sock, cf->serv->proto), goto early_error );147 CHECK_MALLOC_DO( c->conn = fd_cnx_init(cf->sock, cf->serv->proto), goto fatal_error ); 112 148 113 149 /* In case we are a secure server, handshake now */ 114 150 if (cf->serv->secur) { 115 116 TODO("Continue");117 }151 CHECK_FCT_DO( fd_cnx_handshake(c->conn, GNUTLS_CLIENT), goto cleanup ); 152 } 153 118 154 119 155 /* Save the client in the list */ 120 CHECK_POSIX_DO( pthread_mutex_lock( &cf->serv->clients_mtx ), goto early_error );156 CHECK_POSIX_DO( pthread_mutex_lock( &cf->serv->clients_mtx ), goto fatal_error ); 121 157 fd_list_insert_before(&cf->serv->clients, &c->chain); 122 CHECK_POSIX_DO( pthread_mutex_unlock( &cf->serv->clients_mtx ), goto error ); 123 124 125 126 127 early_error: 128 TRACE_DEBUG(INFO, "Thread is detaching to die"); 129 pthread_detach(pthread_self()); 130 shutdown(cf->sock, SHUT_RDWR); 158 CHECK_POSIX_DO( pthread_mutex_unlock( &cf->serv->clients_mtx ), goto fatal_error ); 159 160 /* Start the client thread */ 161 CHECK_POSIX_DO( pthread_create( &c->cli_thr, NULL, client_simple_psm, c ), goto fatal_error ); 162 163 /* We're done here */ 164 free(cf); 165 return NULL; 166 167 cleanup: /* Clean all objects and return (minor error on the connection)*/ 168 if (c && c->conn) { 169 TODO( "Free the c->conn object & gnutls data" ); 170 } 171 172 return NULL; 173 174 fatal_error: /* This has effect to terminate the daemon */ 175 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), ); 131 176 free(cf); 132 177 free(c); 133 error:134 TRACE_DEBUG(INFO, "Thread is terminating");135 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), );136 178 return NULL; 137 179 } … … 142 184 struct server *sv = (struct server *)arg; 143 185 struct cli_fast cf; 186 pthread_attr_t attr; 144 187 145 188 CHECK_PARAMS_DO(sv, goto error); … … 150 193 cf.serv = sv; 151 194 195 CHECK_POSIX_DO( pthread_attr_init(&attr), goto error ); 196 CHECK_POSIX_DO( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED), goto error ); 152 197 153 198 /* Accept incoming connections */ … … 171 216 172 217 /* Create the thread to handle the new incoming connection */ 173 CHECK_POSIX_DO( pthread_create( &thr /* we don't use it, but NULL is not standard */, NULL, handle_client_fast, ncf), goto error );218 CHECK_POSIX_DO( pthread_create( &thr, &attr, handle_client_fast, ncf), goto error ); 174 219 175 220 } while (1); … … 231 276 ((sv->serv_status == 2) ? "Thread terminated" : 232 277 "Thread status unknown"))); 233 /* Dump the endpoints ?*/234 /* Dump the client list ? */278 /* Dump the client list */ 279 TODO("Dump client list"); 235 280 } 236 281 } … … 251 296 CHECK_FCT( fd_sctp_create_bind_server( &socket, fd_g_config->cnf_port ) ); 252 297 CHECK_MALLOC( sv = new_serv(IPPROTO_SCTP, 0, socket) ); 253 254 255 298 TODO("Link"); 299 TODO("Start thread"); 300 301 /* Create the server on secure port */ 256 302 257 303 #endif /* DISABLE_SCTP */ … … 261 307 if (!fd_g_config->cnf_flags.no_tcp) { 262 308 263 309 if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) { 310 /* if not no_IP : create server for 0.0.0.0 */ 311 /* if not no_IP6 : create server for :: */ 312 } else { 313 /* Create all endpoints -- check flags */ 314 } 264 315 } 265 316 … … 270 321 void fd_servers_stop() 271 322 { 272 273 } 323 /* Loop on all servers */ 324 /* cancel thread */ 325 /* shutdown the socket */ 326 /* empty list of clients (stop them) */ 327 } -
libfreeDiameter/fifo.c
r14 r21 136 136 } 137 137 138 /* Delete a queue. It must be unused. */138 /* Delete a queue. It must be empty. */ 139 139 int fd_fifo_del ( struct fifo ** queue ) 140 140 { 141 141 struct fifo * q; 142 int loops = 0; 142 143 143 144 TRACE_ENTRY( "%p", queue ); … … 149 150 CHECK_POSIX( pthread_mutex_lock( &q->mtx ) ); 150 151 151 if ((q->count != 0) || (q->thrs != 0) || (q->data != NULL)) { 152 TRACE_DEBUG(INFO, "The queue cannot be destroyed (%d, %d, %p)", q->count, q->thrs, q->data); 152 /* Ok, now invalidate the queue */ 153 q->eyec = 0xdead; 154 155 if ((q->count != 0) || (q->data != NULL)) { 156 TRACE_DEBUG(INFO, "The queue cannot be destroyed (%d, %p)", q->count, q->data); 153 157 CHECK_POSIX_DO( pthread_mutex_unlock( &q->mtx ), /* no fallback */ ); 154 158 return EINVAL; 155 159 } 156 160 161 while (q->thrs) { 162 CHECK_POSIX( pthread_cond_signal(&q->cond) ); 163 CHECK_POSIX( pthread_mutex_unlock( &q->mtx )); 164 pthread_yield(); 165 CHECK_POSIX( pthread_mutex_lock( &q->mtx ) ); 166 ASSERT( ++loops < 10 ); /* detect infinite loops */ 167 } 168 157 169 /* sanity check */ 158 170 ASSERT(FD_IS_LIST_EMPTY(&q->list)); 159 160 /* Ok, now invalidate the queue */161 q->eyec = 0xdead;162 171 163 172 /* And destroy it */ … … 379 388 awaken: 380 389 /* Check queue status */ 390 if (!CHECK_FIFO( queue )) { 391 /* The queue is being destroyed */ 392 CHECK_POSIX( pthread_mutex_unlock( &queue->mtx ) ); 393 TRACE_DEBUG(FULL, "The queue is being destroyed -> EPIPE"); 394 return EPIPE; 395 } 396 381 397 if (queue->count > 0) { 382 398 /* There are items in the queue, so pick the first one */
Note: See TracChangeset
for help on using the changeset viewer.