📄 ucast.c
字号:
return HA_FAIL; if ((ei->rsocket = HB_make_receive_sock(mp)) < 0) { ucast_close(mp); return HA_FAIL; } PILCallLog(LOG, PIL_INFO, "ucast: started on port %d interface %s to %s", localudpport, ei->interface, inet_ntoa(ei->addr.sin_addr)); return HA_OK;}/* * Close UDP/IP unicast heartbeat interface */static int ucast_close(struct hb_media* mp){ struct ip_private *ei; int rc = HA_OK; UCASTASSERT(mp); ei = (struct ip_private*)mp->pd; if (ei->rsocket >= 0) { if (close(ei->rsocket) < 0) rc = HA_FAIL; } if (ei->wsocket >= 0) { if (close(ei->wsocket) < 0) rc = HA_FAIL; } return rc;}/* * Receive a heartbeat unicast packet from UDP interface */static void *ucast_read(struct hb_media* mp, int *lenp){ struct ip_private *ei; int addr_len; struct sockaddr_in their_addr; int numbytes; char buf[MAXLINE]; void *pkt; UCASTASSERT(mp); ei = (struct ip_private*)mp->pd; addr_len = sizeof(struct sockaddr); if ((numbytes = recvfrom(ei->rsocket, buf, MAXLINE-1, 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { if (errno != EINTR) { PILCallLog(LOG, PIL_CRIT, "ucast: error receiving from socket: %s", strerror(errno)); } return NULL; } if (numbytes == 0) { PILCallLog(LOG, PIL_CRIT, "ucast: received zero bytes"); return NULL; } buf[numbytes] = EOS; if (DEBUGPKT) { PILCallLog(LOG, PIL_DEBUG, "ucast: received %d byte packet from %s", numbytes, inet_ntoa(their_addr.sin_addr)); } if (DEBUGPKTCONT) { PILCallLog(LOG, PIL_DEBUG, "%s", buf); } pkt = ha_malloc(numbytes + 1); if(!pkt){ PILCallLog(LOG, PIL_CRIT , "Error in allocating memory"); return(NULL); } memcpy(pkt, buf, numbytes + 1); *lenp = numbytes +1; return(pkt); }/* * Send a heartbeat packet over unicast UDP/IP interface */static intucast_write(struct hb_media* mp, void *pkt, int len){ struct ip_private *ei; int rc; UCASTASSERT(mp); ei = (struct ip_private*)mp->pd; if ((rc = sendto(ei->wsocket, pkt, len, 0 , (struct sockaddr *)&ei->addr , sizeof(struct sockaddr))) != len) { PILCallLog(LOG, PIL_CRIT, "Unable to send [%d] ucast packet: %s" , rc, strerror(errno)); return HA_FAIL; } if (DEBUGPKT) { PILCallLog(LOG, PIL_DEBUG, "ucast: sent %d bytes to %s", rc, inet_ntoa(ei->addr.sin_addr)); } if (DEBUGPKTCONT) { PILCallLog(LOG, PIL_DEBUG, "%s", (const char*)pkt); } return HA_OK; }/* * Set up socket for sending unicast UDP heartbeats */static int HB_make_send_sock(struct hb_media *mp){ int sockfd; struct ip_private *ei; int tos;#if defined(SO_BINDTODEVICE) struct ifreq i;#endif UCASTASSERT(mp); ei = (struct ip_private*)mp->pd; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { PILCallLog(LOG, PIL_CRIT, "ucast: Error creating write socket: %s", strerror(errno)); } /* * 21 December 2002 * Added by Brian TInsley <btinsley@emageon.com> */ tos = IPTOS_LOWDELAY; if (setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { PILCallLog(LOG, PIL_CRIT, "ucast: error setting socket option IP_TOS: %s", strerror(errno)); } else { PILCallLog(LOG, PIL_INFO, "ucast: write socket priority set to IPTOS_LOWDELAY on %s", ei->interface); }#if defined(SO_BINDTODEVICE) { /* * We want to send out this particular interface * * This is so we can have redundant NICs, and heartbeat on both */ strcpy(i.ifr_name, ei->interface); if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1) { PILCallLog(LOG, PIL_CRIT, "ucast: error setting option SO_BINDTODEVICE(w) on %s: %s", i.ifr_name, strerror(errno)); close(sockfd); return -1; } PILCallLog(LOG, PIL_INFO, "ucast: bound send socket to device: %s", i.ifr_name); }#endif if (fcntl(sockfd,F_SETFD, FD_CLOEXEC) < 0) { PILCallLog(LOG, PIL_CRIT, "ucast: error setting close-on-exec flag: %s", strerror(errno)); } return sockfd;}/* * Set up socket for listening to heartbeats (UDP unicast) */static int HB_make_receive_sock(struct hb_media *mp) { struct ip_private *ei; struct sockaddr_in my_addr; int sockfd; int bindtries; int boundyet = 0; int j; UCASTASSERT(mp); ei = (struct ip_private*)mp->pd; memset(&(my_addr), 0, sizeof(my_addr)); /* zero my address struct */ my_addr.sin_family = AF_INET; /* host byte order */ my_addr.sin_port = htons(ei->port); /* short, network byte order */ my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { PILCallLog(LOG, PIL_CRIT, "ucast: error creating read socket: %s", strerror(errno)); return -1; } /* * Set SO_REUSEADDR on the server socket s. Variable j is used * as a scratch varable. * * 16th February 2000 * Added by Horms <horms@vergenet.net> * with thanks to Clinton Work <work@scripty.com> */ j = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j) < 0) { /* Ignore it. It will almost always be OK anyway. */ PILCallLog(LOG, PIL_CRIT, "ucast: error setting socket option SO_REUSEADDR: %s", strerror(errno)); } #if defined(SO_BINDTODEVICE) { /* * We want to receive packets only from this interface... */ struct ifreq i; strcpy(i.ifr_name, ei->interface); if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1) { PILCallLog(LOG, PIL_CRIT, "ucast: error setting option SO_BINDTODEVICE(r) on %s: %s", i.ifr_name, strerror(errno)); close(sockfd); return -1; } PILCallLog(LOG, PIL_INFO, "ucast: bound receive socket to device: %s", i.ifr_name); }#endif /* Try binding a few times before giving up */ /* Sometimes a process with it open is exiting right now */ for (bindtries=0; !boundyet && bindtries < MAXBINDTRIES; ++bindtries) { if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) < 0) { PILCallLog(LOG, PIL_CRIT, "ucast: error binding socket. Retrying: %s", strerror(errno)); sleep(1); } else{ boundyet = 1; } } if (!boundyet) {#if !defined(SO_BINDTODEVICE) if (errno == EADDRINUSE) { /* This happens with multiple udp or ppp interfaces */ PILCallLog(LOG, PIL_INFO, "ucast: someone already listening on port %d [%s]", ei->port, ei->interface); PILCallLog(LOG, PIL_INFO, "ucast: UDP read process exiting"); close(sockfd); cleanexit(0); }#else PILCallLog(LOG, PIL_CRIT, "ucast: unable to bind socket. Giving up: %s", strerror(errno)); close(sockfd); return -1;#endif } if (fcntl(sockfd,F_SETFD, FD_CLOEXEC) < 0) { PILCallLog(LOG, PIL_CRIT, "ucast: error setting close-on-exec flag: %s", strerror(errno)); } return sockfd;}static struct ip_private* new_ip_interface(const char *ifn, const char *hbaddr, int port){ struct ip_private *ep; struct hostent *h; /* * 21 December 2002 * Added by Brian TInsley <btinsley@emageon.com> */ if (!(h = gethostbyname(hbaddr))) { PILCallLog(LOG, PIL_CRIT, "ucast: cannot resolve hostname"); return NULL; } if (!(ep = (struct ip_private*) MALLOC(sizeof(struct ip_private)))) { PILCallLog(LOG, PIL_CRIT, "ucast: memory allocation error (line %d)", (__LINE__ - 2) ); return NULL; } /* * use address from gethostbyname */ memcpy(&ep->heartaddr, h->h_addr_list[0], sizeof(ep->heartaddr)); if (!(ep->interface = STRDUP(ifn))) { PILCallLog(LOG, PIL_CRIT, "ucast: memory allocation error (line %d)", (__LINE__ - 2) ); FREE(ep); return NULL; } bzero(&ep->addr, sizeof(ep->addr)); /* zero the struct */ ep->addr.sin_family = AF_INET; /* host byte order */ ep->addr.sin_port = htons(port); /* short, network byte order */ ep->port = port; ep->wsocket = -1; ep->rsocket = -1; ep->addr.sin_addr = ep->heartaddr; return ep;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -