receiver.h File Reference


Detailed Description

CDiameterPeer Receiver process procedures.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

Definition in file receiver.h.

#include "peer.h"
#include "diameter.h"

Go to the source code of this file.

Defines

#define DP_MAX_MSG_LENGTH   65536
 Maximum incoming message length.

Functions

void receiver_init (int sock, peer *p)
 Initializes the receiver.
void receiver_process (int sock)
 The Receiver Process - calls the receiv_loop and it never returns.
int peer_connect (peer *p)
 Initiate a connection to a peer.
int peer_send (peer *p, int sock, AAAMessage *msg, int locked)
 Send a message to a peer (only to be called from the receiver process).
int peer_send_msg (peer *p, AAAMessage *msg)
 Sends a message to a peer (to be called from other processes).


Define Documentation

#define DP_MAX_MSG_LENGTH   65536

Maximum incoming message length.

Definition at line 64 of file receiver.h.

Referenced by receive_loop().


Function Documentation

void receiver_init ( int  sock,
peer p 
)

Initializes the receiver.

Parameters:
sock - the socket to initialize with
p - the peer to initialize with

Definition at line 114 of file receiver.c.

References errno, pipe_fd, pipe_fd_out, pipe_name, PIPE_PREFIX, set_peer_pipe(), and this_peer.

Referenced by accept_connection().

00115 {
00116     this_peer = p;
00117     
00118     pipe_name.s = shm_malloc(sizeof(PIPE_PREFIX)+64);
00119     sprintf(pipe_name.s,"%s%d_%d_%d",PIPE_PREFIX,(unsigned int) time(0),sock,getpid());
00120     pipe_name.len = strlen(pipe_name.s);
00121         
00122     set_peer_pipe();    
00123 
00124     mkfifo(pipe_name.s, 0666);  
00125     pipe_fd = open(pipe_name.s, O_RDONLY | O_NDELAY);
00126     if (pipe_fd<0){
00127         LOG(L_ERR,"ERROR:receiver_process(): FIFO open failed > %s\n",strerror(errno));
00128     }
00129     // we open it for writting just to keep it alive - won't close when all other writers close it
00130     pipe_fd_out = open(pipe_name.s, O_WRONLY);
00131 }

void receiver_process ( int  sock  ) 

The Receiver Process - calls the receiv_loop and it never returns.

Parameters:
sock - socket to receive data from
Returns:
never, when disconnected it will exit

Definition at line 138 of file receiver.c.

References dp_del_pid(), _peer_t::lock, memlog, pipe_fd, pipe_fd_out, pipe_name, receive_loop(), _peer_t::send_pipe, and this_peer.

Referenced by accept_connection().

00139 {
00140     LOG(L_INFO,"INFO:receiver_process(): [%d] Receiver process starting up...\n",sock);
00141 
00142         
00143     receive_loop(sock);
00144     LOG(L_INFO,"INFO:receiver_process(): [%d]... Receiver process cleaning-up.\n",sock);
00145     close(sock);
00146     close(pipe_fd);
00147     close(pipe_fd_out);
00148     remove(pipe_name.s);
00149     if (this_peer){
00150         lock_get(this_peer->lock);
00151         this_peer->send_pipe.s=0;
00152         this_peer->send_pipe.len=0;
00153         lock_release(this_peer->lock);
00154     }
00155     shm_free(pipe_name.s);
00156 //done:     
00157     /* remove pid from list of running processes */
00158     dp_del_pid(getpid());
00159     
00160 #ifdef CDP_FOR_SER
00161     drop_my_process();      
00162 #else
00163 #ifdef PKG_MALLOC
00164     #ifdef PKG_MALLOC
00165         LOG(memlog, "Receiver[%d] Memory status (pkg):\n",sock);
00166         //pkg_status();
00167         #ifdef pkg_sums
00168             pkg_sums();
00169         #endif 
00170     #endif
00171 #endif
00172 #endif      
00173         
00174     LOG(L_INFO,"INFO:receiver_process(): [%d]... Receiver process finished.\n",sock);
00175     exit(0);
00176 }

int peer_connect ( peer p  ) 

Initiate a connection to a peer.

Parameters:
p - peer to connect to
Returns:
socket if OK, -1 on error

Definition at line 350 of file receiver.c.

References errno, _peer_t::fqdn, and _peer_t::port.

Referenced by I_Snd_Conn_Req().

00351 {
00352     int sock;
00353     int pid;
00354     unsigned int option = 1;
00355     
00356     struct addrinfo *ainfo=0,*res=0,hints;      
00357     char buf[256],host[256],serv[256];
00358     int error;
00359 
00360     memset (&hints, 0, sizeof(hints));
00361     //hints.ai_protocol = IPPROTO_SCTP;
00362     //hints.ai_protocol = IPPROTO_TCP;
00363     hints.ai_flags = AI_ADDRCONFIG;
00364     hints.ai_socktype = SOCK_STREAM;
00365     
00366     sprintf(buf,"%d",p->port);
00367 
00368     error = getaddrinfo(p->fqdn.s, buf, &hints, &res);
00369 
00370     if (error!=0){
00371         LOG(L_WARN,"WARNING:peer_connect(): Error opening connection to %.*s:%d >%s\n",
00372             p->fqdn.len,p->fqdn.s,p->port,gai_strerror(error));
00373         goto error;
00374     }
00375         
00376     for(ainfo = res;ainfo;ainfo = ainfo->ai_next)
00377     {
00378         if (getnameinfo(ainfo->ai_addr,ainfo->ai_addrlen,
00379             host,256,serv,256,NI_NUMERICHOST|NI_NUMERICSERV)==0){
00380                 LOG(L_WARN,"INFO:peer_connect(): Trying to connect to %s port %s\n",
00381                     host,serv);
00382         }               
00383 
00384         if ((sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) == -1) {
00385             LOG(L_ERR,"ERROR:create_socket(): error creating client socket to %s port %s >"
00386                 " %s\n",host,serv,strerror(errno));
00387             continue;
00388         }
00389 
00390         if (connect(sock,ainfo->ai_addr,ainfo->ai_addrlen)!=0) {
00391             LOG(L_WARN,"WARNING:peer_connect(): Error opening connection to to %s port %s >%s\n",
00392                 host,serv,strerror(errno));
00393             close(sock);        
00394             continue;
00395         }
00396     
00397         setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
00398     
00399         LOG(L_INFO,"INFO:peer_connect(): Peer %.*s:%d connected\n",p->fqdn.len,p->fqdn.s,p->port);
00400 
00401     
00402         receiver_init(sock,p);
00403     
00404         #ifdef CDP_FOR_SER
00405             pid = fork_process(p->port,"receiver I",0);
00406         #else
00407             pid = fork();
00408         #endif
00409         if (pid<0){
00410             LOG(L_ERR,"ERROR:peer_connect(): fork() failed > %s\n",strerror(errno));
00411             goto error;
00412         }
00413         if (pid==0){
00414             /* child */
00415             receiver_process(sock);
00416             LOG(L_CRIT,"ERROR:peer_connect(): receiver_process finished without exit!\n");
00417             exit(-1);
00418         }else{
00419             /* parent */
00420             LOG(L_INFO,"INFO:peer_connect(): Receiver process forked [%d]\n",pid);
00421             
00422             dp_add_pid(pid);
00423         }
00424         
00425         if (res) freeaddrinfo(res);         
00426         return sock;
00427     }
00428 error:
00429     if (res) freeaddrinfo(res); 
00430     return -1;  
00431 }

int peer_send ( peer p,
int  sock,
AAAMessage msg,
int  locked 
)

Send a message to a peer (only to be called from the receiver process).

This directly writes the message on the socket. It is used for transmission during the Capability Exchange procedure, when the send pipes are not opened yet.

Parameters:
p - the peer to send to
sock - the socket to send through
msg - the message to send
locked - whether the caller locked the peer already
Returns:
1 on success, 0 on error

Definition at line 483 of file receiver.c.

References AAABuildMsgBuffer(), AAAFreeMessage(), _message_t::buf, errno, I_Peer_Disc, _peer_t::I_sock, _peer_t::lock, R_Peer_Disc, and sm_process().

Referenced by Snd_CEA().

00484 {
00485     int n;
00486 //  LOG(L_CRIT,"[%d]\n",sock);
00487     
00488     if (!p||!msg||sock<0) return 0;
00489     
00490     if (!AAABuildMsgBuffer(msg)) return 0;
00491     
00492     if (!locked) lock_get(p->lock);
00493 
00494     while( (n=write(sock,msg->buf.s,msg->buf.len))==-1 ) {
00495         if (errno==EINTR)
00496             continue;
00497         LOG(L_ERR,"ERROR:peer_send(): write returned error: %s\n",
00498             strerror(errno));
00499         if (p->I_sock==sock) sm_process(p,I_Peer_Disc,0,1,p->I_sock);
00500         if (p->R_sock==sock) sm_process(p,R_Peer_Disc,0,1,p->R_sock);
00501         if (!locked) lock_release(p->lock);
00502         AAAFreeMessage(&msg);       
00503         return 0;
00504     }
00505 
00506     if (n!=msg->buf.len){
00507         LOG(L_ERR,"ERROR:peer_send(): only wrote %d/%d bytes\n",n,msg->buf.len);
00508         if (!locked) lock_release(p->lock);
00509         AAAFreeMessage(&msg);       
00510         return 0;
00511     }
00512     if (!locked) lock_release(p->lock);
00513     AAAFreeMessage(&msg);           
00514     return 1;   
00515 }

int peer_send_msg ( peer p,
AAAMessage msg 
)

Sends a message to a peer (to be called from other processes).

This just writes the pointer to the message in the send pipe. The specific peer process will pick that up and send the message, as only that specific process has the id of socket (we are forking the peers dynamically and as such, the sockets are not visible between processes).

Parameters:
p - the peer to send to
msg - the message to send
Returns:
1 on success, 0 on failure

Definition at line 444 of file receiver.c.

References AAABuildMsgBuffer(), errno, _peer_t::fqdn, and _peer_t::send_pipe.

Referenced by AAASendMessage(), AAASendMessageToPeer(), AAASendRecvMessage(), AAASendRecvMessageToPeer(), api_callback(), I_Snd_CER(), Snd_DPA(), Snd_DPR(), Snd_DWA(), Snd_DWR(), and Snd_Message().

00445 {
00446     int fd,n;
00447     if (!AAABuildMsgBuffer(msg)) return 0;
00448     if (!p->send_pipe.s) {
00449         LOG(L_ERR,"ERROR:peer_send_msg(): Peer %.*s has no attached send pipe\n",p->fqdn.len,p->fqdn.s);
00450         return 0;
00451     }
00452     fd = open(p->send_pipe.s,O_WRONLY);
00453     if (fd<0){
00454         LOG(L_ERR,"ERROR:peer_send_msg(): Peer %.*s error on pipe open > %s\n",p->fqdn.len,p->fqdn.s,strerror(errno));      
00455         return 0;
00456     }
00457     LOG(L_DBG,"DBG:peer_send_msg(): Pipe push [%p]\n",msg);
00458     n = write(fd,&msg,sizeof(AAAMessage *));
00459     if (n<0) {
00460         LOG(L_ERR,"ERROR:peer_send_msg(): Peer %.*s error on pipe write > %s\n",p->fqdn.len,p->fqdn.s,strerror(errno));     
00461         close(fd);
00462         return 0;
00463     }
00464     if (n!=sizeof(AAAMessage *)) {
00465         LOG(L_ERR,"ERROR:peer_send_msg(): Peer %.*s error on pipe write > only %d bytes written\n",p->fqdn.len,p->fqdn.s,n);        
00466         close(fd);
00467         return 0;
00468     }
00469     close(fd);
00470     return 1;
00471 }


Generated on Sat Sep 6 04:17:50 2008 for Open IMS Core CSCFs by  doxygen 1.5.2