int MPI_Ssend_init(MPE_CONST void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) { int returnVal; request_list *newrq; int typesize3; /* fprintf( stderr, "MPI_Ssend_init call on %d\n", procid_1 ); */ returnVal = PMPI_Ssend_init( buf, count, datatype, dest, tag, comm, request ); if (dest != MPI_PROC_NULL) { rq_alloc( requests_avail_1, newrq ); if (newrq) { PMPI_Type_size( datatype, &typesize3 ); newrq->request = *request; newrq->status = RQ_SEND; newrq->size = count * typesize3; newrq->tag = tag; newrq->otherParty = dest; newrq->next = 0; rq_add( requests_head_1, requests_tail_1, newrq ); } } return returnVal; }
int MPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request) { int returnVal; request_list *newrq1; returnVal = PMPI_Recv_init( buf, count, datatype, source, tag, comm, request ); if (source != MPI_PROC_NULL && returnVal == MPI_SUCCESS) { if ((newrq1 = (request_list*) malloc(sizeof( request_list )))) { newrq1->request = *request; newrq1->status = RQ_RECV; newrq1->next = 0; rq_add( requests_head_1, requests_tail_1, newrq1 ); } } return returnVal; }
// process a client packet void process_client(uint32_t ip, uint16_t port, DnsPkt *pkt, int len) { shm->stats.dns_queries++; // pick up a server for this message uint32_t server_ip = 0; if (last_server == 1) { // try server 2 if (shm->config.name_server2 != 0) { last_server = 2; server_ip = shm->config.name_server2; } else server_ip = shm->config.name_server1; } else if (last_server == 2) { // try server 1n if (shm->config.name_server1 != 0) { last_server = 1; server_ip = shm->config.name_server1; } else server_ip = shm->config.name_server2; } else ASSERT(0); if (server_ip == 0) { rcpLog(muxsock, RCP_PROC_DNS, RLOG_DEBUG, RLOG_FC_DNS, "no DNS server configured, packet dropped"); shm->stats.dns_err_no_server++; return; } // get tid uint16_t client_tid = ntohs(pkt->tid); // can we serve the request from cache? if (pkt->dns_query_type == 1 || pkt->dns_query_type == 28|| pkt->dns_query_type == 5) { // only CNAME, A and AAAA records are served from cache const char *name = NULL; char qualified[CLI_MAX_DOMAIN_NAME + 1]; // if this is an unqualified domain name, add the domain name if ((name = is_unqualified( (char *) pkt->dns_query_name)) != NULL) { // build a fully qualified domain name if (strlen(name) + strlen(shm->config.domain_name) > CLI_MAX_DOMAIN_NAME) { // use the incoming name if the result seems to big name = (char *) pkt->dns_query_name; } else { strcpy(qualified, name); strcat(qualified, shm->config.domain_name); name = qualified; } } else name = (char *) pkt->dns_query_name; DnsCache *dc = cache_find(name, pkt->dns_query_type); if (dc != NULL) { rcpLog(muxsock, RCP_PROC_DNS, RLOG_DEBUG, RLOG_FC_DNS, "DSN response from cache - type %u, %s", pkt->dns_query_type, dnspkt_get_real_name(pkt->dns_query_name)); // build a dns packet DnsPkt out; int out_len = dnspkt_build(&out, dc, client_tid); if (out_len <= 12) { ASSERT(0); shm->stats.dns_err_tx++; return; } // build outgoing server address structure static struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_addr.s_addr = htonl(ip); addr.sin_port = htons(port); addr.sin_family = AF_INET; int txlen = sendto(client_sock, &out, out_len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (txlen == -1) { ASSERT(0); shm->stats.dns_err_tx++; return; } shm->stats.dns_answers++; shm->stats.dns_cached_answers++; return; } } // the packet will be forwarded to a server; apply rate limiting if (shm->config.dns_rate_limit && ++rate_limit > shm->config.dns_rate_limit) { shm->stats.dns_err_rate_limit++; rcpLog(muxsock, RCP_PROC_DNS, RLOG_DEBUG, RLOG_FC_DNS, "forwarding rate limit exceeded, packet dropped"); return; } // replace transaction id uint16_t new_tid = get_new_tid(); pkt->tid = htons(new_tid); // queue the request DnsReq *req = rq_malloc(); if (req == NULL) { rcpLog(muxsock, RCP_PROC_DNS, RLOG_WARNING, RLOG_FC_DNS, "request limit exceeded, attempting recovery..."); return; } memset(req, 0, sizeof(DnsReq)); req->client_tid = client_tid; req->new_tid = new_tid; req->client_ip = ip; req->client_port = port; req->server_ip = server_ip; req->query_type = pkt->dns_query_type; strncpy(req->query_name, dnspkt_get_real_name(pkt->dns_query_name), CLI_MAX_DOMAIN_NAME); req->query_name[CLI_MAX_DOMAIN_NAME] = '\0'; rq_add(req); // build outgoing server address structure static struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_addr.s_addr = htonl(server_ip); addr.sin_port = htons(DNS_SERVER_PORT); // send messages to DNS server port (53) addr.sin_family = AF_INET; // forward message to server int txlen = sendto(req->sock, pkt, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (txlen == -1) { shm->stats.dns_err_tx++; return; } rcpLog(muxsock, RCP_PROC_DNS, RLOG_DEBUG, RLOG_FC_DNS, "DNS Query - type %u, %s, forwarded to %d.%d.%d.%d", pkt->dns_query_type, dnspkt_get_real_name(pkt->dns_query_name), RCP_PRINT_IP(server_ip)); }
/** * Callback-function for a file (i.e., LDM data-product) that was missed by a * multicast downstream LDM. The file is queued for reception by other means. * This function returns immediately. * * @param[in] mdl Pointer to the multicast downstream LDM that missed the file. * @param[in] fileId VCMTP file identifier of the missed file. */ static void missedProdFunc( Mdl* const mdl, VcmtpFileId fileId) { rq_add(requestQueue, fileId); }
void *arp(char *ifname) { int sock,i; struct sockaddr_ll ifs; struct ifreq ifr; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if(sock == -1) { fprintf(stderr, "Socket error %d.\n", errno); exit(1); } /* Get the hwaddr and ifindex of the interface */ memset(ifr.ifr_name, 0, IFNAMSIZ); strncpy(ifr.ifr_name, (char *) ifname, IFNAMSIZ); if(ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { syslog(LOG_ERR, "error: ioctl SIOCGIFHWADDR for %s: %s\n", (char *) ifname, strerror(errno)); abort(); } memset(ifs.sll_addr, 0, ETH_ALEN); memcpy(ifs.sll_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); if(ioctl(sock, SIOCGIFINDEX, &ifr) < 0) { syslog(LOG_ERR, "error: ioctl SIOCGIFINDEX for %s: %s", (char *) ifname, strerror(errno)); abort(); } ifs.sll_family = AF_PACKET; ifs.sll_protocol = htons(ETH_P_ARP); ifs.sll_ifindex = ifr.ifr_ifindex; ifs.sll_hatype = ARPHRD_ETHER; ifs.sll_pkttype = PACKET_BROADCAST; ifs.sll_halen = ETH_ALEN; if(bind(sock, (struct sockaddr *)&ifs, sizeof(struct sockaddr_ll)) < 0) { fprintf(stderr, "Bind %s: %d\n", (char *) ifname, errno); abort(); } while (1) { ether_arp_frame frame; unsigned long src; unsigned long dst; struct in_addr sia; struct in_addr dia; do { pthread_testcancel(); /* Sleep a bit in order not to overload the system */ usleep(300); if (arp_recv(sock, &frame) <= 0) continue; /* Insert all the replies into ARP table */ if (frame.arp.arp_op == ntohs(ARPOP_REPLY)) { /* Received frame is an ARP reply */ struct arpreq k_arpreq; int arpsock; struct sockaddr_in *sin; if ((arpsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { syslog(LOG_ERR, "error: ARP socket for %s: %s", (char *) ifname, strerror(errno)); continue; } k_arpreq.arp_ha.sa_family = ARPHRD_ETHER; memcpy(&k_arpreq.arp_ha.sa_data, &frame.arp.arp_sha, sizeof(frame.arp.arp_sha)); k_arpreq.arp_flags = ATF_COM; if (option_arpperm) k_arpreq.arp_flags = k_arpreq.arp_flags | ATF_PERM; strncpy(k_arpreq.arp_dev, ifname, sizeof(k_arpreq.arp_dev)); k_arpreq.arp_pa.sa_family = AF_INET; sin = (struct sockaddr_in *) &k_arpreq.arp_pa; memcpy(&sin->sin_addr.s_addr, &frame.arp.arp_spa, sizeof(sin->sin_addr)); /* Update kernel ARP table with the data from reply */ if (debug) printf("Received reply: updating kernel ARP table for %s(%s).\n", inet_ntoa(sin->sin_addr), (char *) ifname); if (ioctl(arpsock, SIOCSARP, &k_arpreq) < 0) { syslog(LOG_ERR, "error: ioctl SIOCSARP for %s(%s): %s", inet_ntoa(sin->sin_addr), (char *) ifname, strerror(errno)); close(arpsock); continue; } close(arpsock); /* Check if reply is for one of the requests in request queue */ rq_process(sin->sin_addr, ifs.sll_ifindex); /* send gratuitous arp request to all other interfaces to let them * update their ARP tables quickly */ for (i=0; i <= last_iface_idx; i++) { if (strcmp(ifaces[i], ifname)) { arp_req(ifaces[i], sin->sin_addr, 1); } } } } while (frame.arp.arp_op != htons(ARPOP_REQUEST)); /* Received frame is an ARP request */ memcpy(&src,(char *)frame.arp.arp_spa,4); memcpy(&dst,(char *)frame.arp.arp_tpa,4); dia.s_addr = dst; sia.s_addr = src; if (debug) printf("Received ARP request for %s on iface %s\n", inet_ntoa(dia), (char *) ifname); if (memcmp(&dia,&sia,sizeof(dia)) && dia.s_addr != 0) { pthread_mutex_lock(&arptab_mutex); /* Relay the ARP request to all other interfaces */ for (i=0; i <= last_iface_idx; i++) { if (strcmp(ifaces[i], ifname)) { arp_req(ifaces[i], dia, 0); } } /* Add the request to the request queue */ if (debug) printf("Adding %s to request queue\n", inet_ntoa(sia)); rq_add(&frame, &ifs); pthread_mutex_unlock(&arptab_mutex); } } }