static void network_notifier(RECOVERY_STATUS status, int error, const char *msg) { int len = msg ? strlen(msg) : 0; struct msg_elem *newmsg = (struct msg_elem *)calloc(1, sizeof(*newmsg) + len + 1); struct msg_elem *oldmsg; if (!newmsg) return; pthread_mutex_lock(&msglock); nrmsgs++; if (nrmsgs > NUM_CACHED_MESSAGES) { oldmsg = SIMPLEQ_FIRST(¬ifymsgs); SIMPLEQ_REMOVE_HEAD(¬ifymsgs, next); free(oldmsg); nrmsgs--; } newmsg->msg = (char *)newmsg + sizeof(struct msg_elem); newmsg->status = status; newmsg->error = error; if (msg) { strncpy(newmsg->msg, msg, len); clean_msg(newmsg->msg, '\t'); clean_msg(newmsg->msg, '\n'); clean_msg(newmsg->msg, '\r'); } SIMPLEQ_INSERT_TAIL(¬ifymsgs, newmsg, next); pthread_mutex_unlock(&msglock); }
void multicast_rcv_cb(evutil_socket_t sock, short ev, void *arg) { static char rcv_buff[MDNS_MAX_LEN], ans_buff[MDNS_MAX_LEN]; static struct sockaddr_in from_addr; static int rcv_len, snd_len; static unsigned int from_len; static dns_msg_t rcv, ans; static dns_resource_t ans_r; static dns_question_t ans_q; static int i, j, jj, fnd, asknm; static char * tmp_buff; uint32_t rcv_ip; init_msg(&rcv); memset(rcv_buff, 0, sizeof(rcv_buff)); memset(&from_addr, 0, sizeof(from_addr)); if ((rcv_len = recvfrom(sock, rcv_buff, MDNS_MAX_LEN, 0, (struct sockaddr*)&from_addr, &from_len)) < 0) { return; } // printf("Received %d bytes from %s: ", rcv_len, // inet_ntoa(from_addr.sin_addr)); fflush(stdout); if(message_from_network(&rcv, rcv_buff, MDNS_MAX_LEN) < 0) { printf("bledna wiadomosc\n"); } else if(get_QR(&(rcv.header)) == QR_QUERY) { for(i = 0; i < get_QDCOUNT(&(rcv.header)); ++i) { if(answer(rcv.questions + i, &ans_r, my_ip) == 0) { //potrafie odpowiedziec init_msg(&ans); set_QR(&(ans.header), QR_RESPONSE); set_ANCOUNT(&(ans.header), 1); ans.answers = &ans_r; snd_len = send_format_msg(&ans, ans_buff); if(sendto(sock, ans_buff, snd_len, 0, // TODO unicast (struct sockaddr *) &multicast_addr, sizeof(multicast_addr)) != snd_len) { fprintf(stderr, "nie udalo sie odpowiedziec na A :c\n"); } } } } else {//if (get_QR(&(rcv.header)) == QR_RESPONSE) for(i = 0; i < get_ANCOUNT(&(rcv.header)); ++i) { if (is_rA(rcv.answers + i)) { for(jj = 0; jj < 4; ++jj){ } rcv_ip = ntohl (*((uint32_t *)rcv.answers[i].RDATA)); if (names_equal(rcv.answers[i].NAME + rcv.answers[i].NAME[0] + 1, UDP_SERV)) { for(j = 0; j < MAX_IPS; ++j) { if (names_equal(found_UDP[j], rcv.answers[i].NAME)) break; } if (j == MAX_IPS) continue; for(jj = 0; jj < MAX_IPS; ++jj) { if (found_ips[jj].ip == rcv_ip) break; } if (jj == MAX_IPS) { for(jj = 0; jj < MAX_IPS; ++jj) if(!found_ips[jj].ip) { found_ips[jj].ip = rcv_ip; break; } } if (jj == MAX_IPS) continue; // no bez przesady to sie nie zdarzy if(found_ips[jj].ev[0]) continue; found_ips[jj].udp_i = j; found_ips[jj].ev[0] = event_new(main_loop, -1, EV_TIMEOUT | EV_PERSIST, udp_delays_ask_cb, (void*) &jj); event_add(found_ips[jj].ev[0], &del_tv); } else if (names_equal( rcv.answers[i].NAME + rcv.answers[i].NAME[0] + 1, TCP_SERV)) { for(j = 0; j < MAX_IPS; ++j) { if (names_equal(found_TCP[j], rcv.answers[i].NAME)) break; } if (j == MAX_IPS) continue; //ta nazwa jeszcze nigdy nie byla szukana for(jj = 0; jj < MAX_IPS; ++jj) { if (found_ips[jj].ip == rcv_ip) break; } if (jj == MAX_IPS) { for(jj = 0; jj < MAX_IPS; ++jj) if(!found_ips[jj].ip) { found_ips[jj].ip = rcv_ip; break; } } if (jj == MAX_IPS) continue; // no bez przesady to sie nie zdarzy if(found_ips[jj].ev[0]) continue; found_ips[jj].tcp_i = j; found_ips[jj].ev[1] = event_new(main_loop, -1, EV_TIMEOUT | EV_PERSIST, tcp_delay_cb, (void*) &jj); event_add(found_ips[jj].ev[0], &del_tv); } } else if (is_rPTR(rcv.answers + i)) { asknm = 0; if(rPTR_my_name(rcv.answers + i, rcv_buff)) continue; // zmien nazwe komputera tmp_buff = (char *) malloc(sizeof(char) * NAME_MLENGTH); memset(tmp_buff, 0, sizeof(char) * NAME_MLENGTH); get_NAME_from_net(tmp_buff, rcv.answers[i].RDATA, rcv.answers[i].RDLENGTH, rcv_buff); if(rPTR_UDP(rcv.answers + i, rcv_buff)) { asknm = 1; fnd = 0; for(j = 0; j < MAX_IPS; ++j){ if(found_UDP[i]) { if (names_equal(found_UDP[j], tmp_buff)){ fnd = 1; asknm = 0; break; } } } for(j = 0; !fnd && (j < MAX_IPS); ++j) { if (found_UDP[j] == NULL) break; } if(j >= MAX_IPS || fnd) free(tmp_buff); else found_UDP[j] = tmp_buff; } else if(rPTR_TCP(rcv.answers + i, rcv_buff)) { fnd = 0; asknm = 1; for(j = 0; j < MAX_IPS; ++j){ if(found_TCP[j]) { if (names_equal(found_TCP[j], tmp_buff)){ fnd = 1; asknm = 0; break; } } } for(j = 0; !fnd && (j < MAX_IPS); ++j) { if (found_TCP[j] == NULL) break; } if(j >= MAX_IPS || fnd) free(tmp_buff); else found_TCP[j] = tmp_buff; } else free(tmp_buff); if(asknm) { ask_A(tmp_buff, &ans_q); init_msg(&ans); set_QR(&(ans.header), QR_QUERY); set_QDCOUNT(&(ans.header), 1); ans.questions = &ans_q; snd_len = send_format_msg(&ans, ans_buff); if(sendto(sock, ans_buff, snd_len, 0, (struct sockaddr *) &multicast_addr, sizeof(multicast_addr)) != snd_len) { fprintf(stderr, "nie udalo sie zapytc o A :c\n"); } } } } } clean_msg(&rcv); }