Changeset 12:418d2ce80dc8 in freeDiameter
- Timestamp:
- Sep 28, 2009, 5:29:25 PM (15 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/freediameter.conf.sample
r10 r12 7 7 # This must be a valid FQDN that resolves to the local host. 8 8 # Default: hostname's FQDN 9 # LocalIdentity = "aaa.koganei.wide.ad.jp";9 #Identity = "aaa.koganei.wide.ad.jp"; 10 10 11 11 # The Diameter Realm of this daemon. 12 # Default: the domain part of LocalIdentity.13 # LocalRealm = "wide.ad.jp";12 # Default: the domain part of Identity. 13 #Realm = "wide.ad.jp"; 14 14 15 15 ############################################################## … … 18 18 # The port this peer is listening on for incoming connections (TCP and SCTP). 19 19 # Default: 3868 20 # LocalPort = 3868;20 #Port = 3868; 21 21 22 22 # The port this peer is listening on for incoming TLS connections (TCP and SCTP). 23 23 # See TLS_old_method for more information. 24 24 # Default: 3869 25 # LocalSecPort = 3869;25 #SecPort = 3869; 26 26 27 27 # Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA … … 94 94 #NoRelay; 95 95 96 # Other applications are configured by extensions.96 # Other applications are configured by loading appropriate extensions. 97 97 98 98 ############################################################## … … 105 105 # These extensions may in addition receive the name of a 106 106 # configuration file, the format of which is extension-specific. 107 107 # 108 108 # Format: 109 109 #LoadExtension = "/path/to/extension" [ : "/optional/configuration/file" ] ; 110 # 110 111 # Exemples: 111 112 #LoadExtension = "extensions/sample.so"; … … 113 114 114 115 116 ############################################################## 117 ## Peers configuration 118 119 # The local server listens for incoming connections. By default, 120 # all unknown connecting peers are rejected. Extensions can override this behavior. 121 # 122 # In addition to incoming connections, the local peer can 123 # be configured to establish and maintain connections to some 124 # Diameter nodes and allow connections from these nodes. 125 # This is achieved with the ConnectPeer directive described bellow. 126 # 127 # Note that the configured Diameter Id MUST match 128 # the information received inside CEA, or the connection will be aborted. 129 # 130 # Format: 131 #ConnectPeer = "diameterid" [ { parameter1; parameter2; ...} ] ; 132 # Parameters that can be specified in the peer's parameter list: 133 # No_TCP; No_SCTP; No_IP; No_IPv6; Prefer_TCP; TLS_old_method; 134 # No_TLS; # assume transparent security instead of TLS 135 # Port = 3868; # The port to connect to 136 # SCTP_streams = 30; 137 # TcTimer = 30; 138 # TwTimer = 30; 139 # ConnectTo = "202.249.37.5"; 140 # ConnectTo = "2001:200:903:2::202:1"; 141 # Examples: 142 #ConnectPeer = "aaa.wide.ad.jp"; 143 #ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; } ; 144 115 145 116 146 ############################################################## 117 147 # -------- Test configuration --------- 118 LocalIdentity = "aaa.koganei.wide.ad.jp";119 LocalRealm = "wide.ad.jp";120 LocalPort = 3866;121 LocalSecPort = 3867;148 Identity = "aaa.koganei.wide.ad.jp"; 149 Realm = "wide.ad.jp"; 150 Port = 3866; 151 SecPort = 3867; 122 152 TLS_old_method; 123 153 No_IP; … … 132 162 LoadExtension = "extensions/dict_nasreq.fdx"; 133 163 LoadExtension = "extensions/dict_eap.fdx"; 164 ConnectPeer = "jules.nautilus6.org" ; -
freeDiameter/fD.h
r11 r12 72 72 struct fd_peer { /* The "real" definition of the peer structure */ 73 73 74 struct peer_hdr p_hdr; /* contains all public data */ 74 /* The public data */ 75 struct peer_hdr p_hdr; 75 76 76 int p_eyec; /* Eye catcher, EYEC_PEER */ 77 /* Eye catcher, EYEC_PEER */ 78 int p_eyec; 77 79 #define EYEC_PEER 0x373C9336 78 80 79 /* threads, message queues, socket & callbacks */ 81 /* Origin of this peer object, for debug */ 82 char *p_dbgorig; 83 84 /* Mutex that protect this peer structure */ 85 pthread_mutex_t p_mtx; 86 87 /* Reference counter -- freed only when this reaches 0 */ 88 unsigned p_refcount; 89 90 /* Chaining in peers sublists */ 91 struct fd_list p_expiry; /* list of expiring peers, ordered by their timeout value */ 92 struct fd_list p_actives; /* list of peers in the STATE_OPEN state -- faster routing creation */ 93 94 /* The next hop-by-hop id value for the link */ 95 uint32_t p_hbh; 96 97 /* Some flags influencing the peer state machine */ 98 struct { 99 unsigned pf_responder : 1; /* The local peer is responder on the connection */ 100 101 unsigned pf_dw_pending : 1; /* A DWR message was sent and not answered yet */ 102 103 unsigned pf_cnx_pb : 1; /* The peer was disconnected because of watchdogs; must exchange 3 watchdogs before putting back to normal */ 104 unsigned pf_reopen_cnt : 2; /* remaining DW to be exchanged after re-established connection */ 105 106 /* to be completed */ 107 108 } p_flags; 109 110 /* The events queue, peer state machine thread, timer for states timeouts */ 111 struct fifo *p_events; 112 pthread_t p_psm; 113 struct timespec p_psm_timer; 114 115 /* Received message queue, and thread managing reception of messages */ 116 struct fifo *p_recv; 117 pthread_t p_inthr; 118 119 /* Outgoing message queue, and thread managing sending the messages */ 120 struct fifo *p_tosend; 121 pthread_t p_outthr; 122 123 /* Sent requests (for fallback), list of struct sentreq ordered by hbh */ 124 struct fd_list p_sentreq; 125 126 /* connection context: socket & other metadata */ 127 struct cnxctx *p_cnxctx; 80 128 81 129 }; 130 #define CHECK_PEER( _p ) \ 131 (((_p) != NULL) && (((struct fd_peer *)(_p))->p_eyec == EYEC_PEER)) 82 132 133 /* Events codespace for struct fd_peer->p_events */ 134 enum { 135 /* request to terminate this peer : disconnect, requeue all messages */ 136 FDEVP_TERMINATE = 2000 137 138 /* Dump all info about this peer in the debug log */ 139 ,FDEVP_DUMP_ALL 140 141 /* A message was received in the peer */ 142 ,FDEVP_MSG_INCOMING 143 }; 144 145 /* Structure to store a sent request */ 146 struct sentreq { 147 struct fd_list chain; /* the "o" field points directly to the hop-by-hop of the request (uint32_t *) */ 148 struct msg *req; /* A request that was sent and not yet answered. */ 149 }; 150 151 /* Functions */ 83 152 int fd_peer_init(); 84 void fd_peer_dump (int details);153 void fd_peer_dump_list(int details); 85 154 int fd_peer_start(); 86 155 int fd_peer_waitstart(); 87 156 157 158 88 159 #endif /* _FD_H */ -
freeDiameter/fdd.l
r8 r12 112 112 113 113 /* Full words tokens (keywords) */ 114 (?i:" LocalIdentity") { return LOCALIDENTITY; }115 (?i:" LocalRealm") { return LOCALREALM;}116 (?i:" LocalPort") { return LOCALPORT;}117 (?i:" LocalSecPort") { return LOCALSECPORT;}114 (?i:"Identity") { return IDENTITY; } 115 (?i:"Realm") { return REALM; } 116 (?i:"Port") { return PORT; } 117 (?i:"SecPort") { return SECPORT; } 118 118 (?i:"No_IPv6") { return NOIP6; } 119 119 (?i:"No_IP") { return NOIP; } … … 128 128 (?i:"NoRelay") { return NORELAY; } 129 129 (?i:"LoadExtension") { return LOADEXT; } 130 (?i:"ConnectPeer") { return CONNPEER; } 131 (?i:"ConnectTo") { return CONNTO; } 132 (?i:"No_TLS") { return NOTLS; } 130 133 131 134 -
freeDiameter/fdd.y
r10 r12 70 70 } 71 71 72 int got_peer_noip = 0; 73 int got_peer_noipv6 = 0; 74 int got_peer_notcp = 0; 75 int got_peer_nosctp = 0; 76 77 struct peer_info fddpi; 78 72 79 %} 73 80 74 81 /* Values returned by lex for token */ 75 82 %union { 76 char *string; /* The string is allocated by strdup in lex.*/77 int integer; /* Store integer values */83 char *string; /* The string is allocated by strdup in lex.*/ 84 int integer; /* Store integer values */ 78 85 } 79 86 … … 84 91 %token <integer> INTEGER 85 92 86 %type <string> extconf87 88 %token LOCALIDENTITY89 %token LOCALREALM90 %token LOCALPORT91 %token LOCALSECPORT93 %type <string> extconf 94 95 %token IDENTITY 96 %token REALM 97 %token PORT 98 %token SECPORT 92 99 %token NOIP 93 100 %token NOIP6 … … 96 103 %token PREFERTCP 97 104 %token OLDTLS 105 %token NOTLS 98 106 %token SCTPSTREAMS 99 107 %token LISTENON … … 102 110 %token NORELAY 103 111 %token LOADEXT 112 %token CONNPEER 113 %token CONNTO 104 114 105 115 … … 109 119 /* The grammar definition - Sections blocs. */ 110 120 conffile: /* Empty is OK */ 111 | conffile localidentity112 | conffile localrealm121 | conffile identity 122 | conffile realm 113 123 | conffile tctimer 114 124 | conffile twtimer 115 | conffile localport116 | conffile localsecport125 | conffile port 126 | conffile secport 117 127 | conffile sctpstreams 118 128 | conffile listenon … … 125 135 | conffile oldtls 126 136 | conffile loadext 127 ; 128 129 localidentity: LOCALIDENTITY '=' QSTRING ';' 137 | conffile connpeer 138 | conffile errors 139 { 140 yyerror(&yylloc, conf, "An error occurred while parsing the configuration file"); 141 return EINVAL; 142 } 143 ; 144 145 /* Lexical or syntax error */ 146 errors: LEX_ERROR 147 | error 148 ; 149 150 identity: IDENTITY '=' QSTRING ';' 130 151 { 131 152 conf->cnf_diamid = $3; … … 133 154 ; 134 155 135 localrealm: LOCALREALM '=' QSTRING ';'156 realm: REALM '=' QSTRING ';' 136 157 { 137 158 conf->cnf_diamrlm = $3; … … 155 176 ; 156 177 157 localport: LOCALPORT '=' INTEGER ';'178 port: PORT '=' INTEGER ';' 158 179 { 159 180 CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16), … … 163 184 ; 164 185 165 localsecport: LOCALSECPORT '=' INTEGER ';'186 secport: SECPORT '=' INTEGER ';' 166 187 { 167 188 CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16), … … 210 231 noip: NOIP ';' 211 232 { 233 if (got_peer_noipv6) { 234 yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IPv6."); 235 YYERROR; 236 } 212 237 conf->cnf_flags.no_ip4 = 1; 213 238 } … … 216 241 noip6: NOIP6 ';' 217 242 { 243 if (got_peer_noip) { 244 yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IP."); 245 YYERROR; 246 } 218 247 conf->cnf_flags.no_ip6 = 1; 219 248 } … … 222 251 notcp: NOTCP ';' 223 252 { 253 #ifdef DISABLE_SCTP 254 yyerror (&yylloc, conf, "No_TCP cannot be specified for daemon compiled with DISABLE_SCTP option."); 255 YYERROR; 256 #endif 257 if (conf->cnf_flags.no_sctp) 258 { 259 yyerror (&yylloc, conf, "No_TCP conflicts with No_SCTP directive." ); 260 YYERROR; 261 } 262 if (got_peer_nosctp) { 263 yyerror (&yylloc, conf, "No_TCP conflicts with a ConnectPeer directive No_SCTP."); 264 YYERROR; 265 } 224 266 conf->cnf_flags.no_tcp = 1; 225 267 } … … 228 270 nosctp: NOSCTP ';' 229 271 { 272 if (conf->cnf_flags.no_tcp) 273 { 274 yyerror (&yylloc, conf, "No_SCTP conflicts with No_TCP directive." ); 275 YYERROR; 276 } 277 if (got_peer_notcp) { 278 yyerror (&yylloc, conf, "No_SCTP conflicts with a ConnectPeer directive No_TCP."); 279 YYERROR; 280 } 230 281 conf->cnf_flags.no_sctp = 1; 231 282 } … … 260 311 } 261 312 ; 313 314 connpeer: { 315 memset(&fddpi, 0, sizeof(fddpi)); 316 } 317 CONNPEER '=' QSTRING peerinfo ';' 318 { 319 fddpi.pi_diamid = $4; 320 CHECK_FCT_DO( fd_peer_add ( &fddpi, conf->cnf_file, NULL, NULL ), 321 { yyerror (&yylloc, conf, "Error adding ConnectPeer information"); YYERROR; } ); 322 323 /* Now destroy any content in the structure */ 324 free(fddpi.pi_diamid); 325 while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) { 326 struct fd_list * li = fddpi.pi_endpoints.next; 327 fd_list_unlink(li); 328 free(li); 329 } 330 } 331 ; 332 333 peerinfo: /* empty */ 334 | '{' peerparams '}' 335 ; 336 337 peerparams: /* empty */ 338 | peerparams NOIP ';' 339 { 340 if ((conf->cnf_flags.no_ip6) || (fddpi.pi_flags.pro3 == PI_P3_IP)) { 341 yyerror (&yylloc, conf, "No_IP conflicts with a No_IPv6 directive."); 342 YYERROR; 343 } 344 got_peer_noip++; 345 fddpi.pi_flags.pro3 = PI_P3_IPv6; 346 } 347 | peerparams NOIP6 ';' 348 { 349 if ((conf->cnf_flags.no_ip4) || (fddpi.pi_flags.pro3 == PI_P3_IPv6)) { 350 yyerror (&yylloc, conf, "No_IPv6 conflicts with a No_IP directive."); 351 YYERROR; 352 } 353 got_peer_noipv6++; 354 fddpi.pi_flags.pro3 = PI_P3_IP; 355 } 356 | peerparams NOTCP ';' 357 { 358 #ifdef DISABLE_SCTP 359 yyerror (&yylloc, conf, "No_TCP cannot be specified in daemon compiled with DISABLE_SCTP option."); 360 YYERROR; 361 #endif 362 if ((conf->cnf_flags.no_sctp) || (fddpi.pi_flags.pro4 == PI_P4_TCP)) { 363 yyerror (&yylloc, conf, "No_TCP conflicts with a No_SCTP directive."); 364 YYERROR; 365 } 366 got_peer_notcp++; 367 fddpi.pi_flags.pro4 = PI_P4_SCTP; 368 } 369 | peerparams NOSCTP ';' 370 { 371 if ((conf->cnf_flags.no_tcp) || (fddpi.pi_flags.pro4 == PI_P4_SCTP)) { 372 yyerror (&yylloc, conf, "No_SCTP conflicts with a No_TCP directive."); 373 YYERROR; 374 } 375 got_peer_nosctp++; 376 fddpi.pi_flags.pro4 = PI_P4_TCP; 377 } 378 | peerparams PREFERTCP ';' 379 { 380 fddpi.pi_flags.alg = PI_ALGPREF_TCP; 381 } 382 | peerparams OLDTLS ';' 383 { 384 if (fddpi.pi_flags.sec == PI_SEC_NONE) { 385 yyerror (&yylloc, conf, "ConnectPeer: TLS_old_method conflicts with No_TLS."); 386 YYERROR; 387 } 388 fddpi.pi_flags.sec = PI_SEC_TLS_OLD; 389 } 390 | peerparams NOTLS ';' 391 { 392 if (fddpi.pi_flags.sec == PI_SEC_TLS_OLD) { 393 yyerror (&yylloc, conf, "ConnectPeer: No_TLS conflicts with TLS_old_method."); 394 YYERROR; 395 } 396 fddpi.pi_flags.sec = PI_SEC_NONE; 397 } 398 | peerparams PORT '=' INTEGER ';' 399 { 400 CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16), 401 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); 402 fddpi.pi_port = (uint16_t)$4; 403 } 404 | peerparams SCTPSTREAMS '=' INTEGER ';' 405 { 406 CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16), 407 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } ); 408 fddpi.pi_streams = (uint16_t)$4; 409 } 410 | peerparams TCTIMER '=' INTEGER ';' 411 { 412 fddpi.pi_tctimer = $4; 413 } 414 | peerparams TWTIMER '=' INTEGER ';' 415 { 416 fddpi.pi_twtimer = $4; 417 } 418 | peerparams CONNTO '=' QSTRING ';' 419 { 420 struct fd_endpoint * ep; 421 struct addrinfo hints, *ai; 422 int ret; 423 424 CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)), 425 { yyerror (&yylloc, conf, "Out of memory"); YYERROR; } ); 426 memset(ep, 0, sizeof(struct fd_endpoint)); 427 fd_list_init(&ep->chain, NULL); 428 429 memset(&hints, 0, sizeof(hints)); 430 hints.ai_flags = AI_ADDRCONFIG; 431 ret = getaddrinfo($4, NULL, &hints, &ai); 432 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; } 433 434 memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen); 435 free($4); 436 freeaddrinfo(ai); 437 fd_list_insert_before(&fddpi.pi_endpoints, &ep->chain); 438 } 439 ; -
freeDiameter/main.c
r11 r12 117 117 118 118 case FDEV_DUMP_PEERS: 119 fd_peer_dump (FULL);119 fd_peer_dump_list(FULL); 120 120 break; 121 121 -
freeDiameter/peers.c
r11 r12 47 47 , "STATE_REOPEN" 48 48 }; 49 #define STATE_STR(state) \50 peer_state_str[ (state) <= STATE_REOPEN ? (state) : 0 ]51 49 52 50 struct fd_list fd_g_peers; … … 94 92 95 93 /* Dump the list of peers */ 96 void fd_peer_dump (int details)94 void fd_peer_dump_list(int details) 97 95 { 98 96 struct fd_list * li; … … 108 106 } 109 107 110 fd_log_debug(" %s %s", np->p_hdr.info.pi_diamid, STATE_STR(np->p_hdr.info.pi_state));108 fd_log_debug(" %s\t%s", STATE_STR(np->p_hdr.info.pi_state), np->p_hdr.info.pi_diamid); 111 109 if (details > INFO) { 112 fd_log_debug(" 110 fd_log_debug("\t(rlm:%s)", np->p_hdr.info.pi_realm); 113 111 if (np->p_hdr.info.pi_prodname) 114 fd_log_debug(" ['%s' %u]", np->p_hdr.info.pi_prodname, np->p_hdr.info.pi_firmrev); 112 fd_log_debug("\t['%s' %u]", np->p_hdr.info.pi_prodname, np->p_hdr.info.pi_firmrev); 113 fd_log_debug("\t(from %s)", np->p_dbgorig); 115 114 } 116 115 fd_log_debug("\n"); … … 119 118 CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); 120 119 } 120 121 /* Add a new peer entry */ 122 int fd_peer_add ( struct peer_info * info, char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data ) 123 { 124 return ENOTSUP; 125 } -
include/freeDiameter/freeDiameter.h
r11 r12 125 125 /* Events codespace for fd_g_config->cnf_main_ev */ 126 126 enum { 127 FDEV_TERMINATE = 1000,/* request to terminate */128 FDEV_DUMP_DICT,/* Dump the content of the dictionary */129 FDEV_DUMP_EXT,/* Dump state of extensions */130 FDEV_DUMP_QUEUES,/* Dump the message queues */131 FDEV_DUMP_CONFIG,/* Dump the configuration */132 FDEV_DUMP_PEERS/* Dump the list of peers */127 FDEV_TERMINATE = 1000 /* request to terminate */ 128 ,FDEV_DUMP_DICT /* Dump the content of the dictionary */ 129 ,FDEV_DUMP_EXT /* Dump state of extensions */ 130 ,FDEV_DUMP_QUEUES /* Dump the message queues */ 131 ,FDEV_DUMP_CONFIG /* Dump the configuration */ 132 ,FDEV_DUMP_PEERS /* Dump the list of peers */ 133 133 }; 134 134 … … 161 161 }; 162 162 extern const char *peer_state_str[]; 163 #define STATE_STR(state) \ 164 peer_state_str[ ((unsigned)(state)) <= STATE_REOPEN ? ((unsigned)(state)) : 0 ] 163 165 164 166 /* Information about a remote peer, used both for query and for creating a new entry */ 165 167 struct peer_info { 166 168 167 /* This information is always there */168 169 char * pi_diamid; /* UTF-8, \0 terminated. The Diameter Identity of the remote peer */ 169 170 char * pi_realm; /* idem, its realm. */ 170 171 171 /* Flags */172 172 struct { 173 #define PI_PROT_DEFAULT 0 /* Use the default algorithm configured for the host */ 174 #define PI_PROT_TCP 1 175 #define PI_PROT_SCTP 2 176 unsigned proto :2; 177 178 #define PI_SEC_DEFAULT 0 /* The default behavior configured for the host */ 173 #define PI_P3_DEFAULT 0 /* Use the default L3 protocol configured for the host */ 174 #define PI_P3_IP 1 /* Use only IP to connect to this peer */ 175 #define PI_P3_IPv6 2 /* resp, IPv6 */ 176 unsigned pro3 :2; 177 178 #define PI_P4_DEFAULT 0 /* Use the default L4 proto configured for the host */ 179 #define PI_P4_TCP 1 /* Only use TCP */ 180 #define PI_P4_SCTP 2 /* Only use SCTP */ 181 unsigned pro4 :2; 182 183 #define PI_ALGPREF_SCTP 0 /* SCTP is initially attempted */ 184 #define PI_ALGPREF_TCP 1 /* TCP is initially attempted */ 185 unsigned alg :1; 186 187 #define PI_SEC_DEFAULT 0 /* New TLS security (dedicated port protecting also CER/CEA) */ 179 188 #define PI_SEC_NONE 1 /* Transparent security with this peer (IPsec) */ 180 #define PI_SEC_TLS_NEW 2 /* New TLS security (dedicated port protecting also CER/CEA) */ 181 #define PI_SEC_TLS_OLD 3 /* Old TLS security (inband on default port) */ 189 #define PI_SEC_TLS_OLD 2 /* Old TLS security (inband on default port) */ 182 190 unsigned sec :2; 183 191 184 #define PI_EXP_DEFAULT 0 185 #define PI_EXP_NONE 1 /* the peer entry does not expire */ 186 #define PI_EXP_INACTIVE 2 /* the peer entry expires after pi_lft seconds without activity */ 187 #define PI_EXP_LIFETIME 3 /* the peer SA information is destroyed after lft seconds (example: DNS timeout) */ 188 unsigned exp :2; 192 #define PI_EXP_NONE 0 /* the peer entry does not expire */ 193 #define PI_EXP_INACTIVE 1 /* the peer entry expires after pi_lft seconds without activity */ 194 unsigned exp :1; 189 195 190 196 /* Following flags are read-only and received from remote peer */ … … 232 238 * PARAMETERS: 233 239 * info : Information to create the peer. 240 * orig_dbg : A string indicating the origin of the peer information, for debug (ex: conf, redirect, ...) 234 241 * cb : optional, a callback to call (once) when the peer connection is established or failed 235 242 * cb_data : opaque data to pass to the callback. … … 248 255 * ENOMEM : Memory allocation for the new object element failed.) 249 256 */ 250 int fd_peer_add ( struct peer_info * info, void (*cb)(struct peer_info *, void *), void * cb_data );257 int fd_peer_add ( struct peer_info * info, char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data ); 251 258 252 259 /*
Note: See TracChangeset
for help on using the changeset viewer.