5 #include <sys/socket.h>
6 #include <netinet/in.h>
20 bool opt_same_interface = false;
22 static int ac_sockfd[AC_NUM];
25 unsigned received, last_received;
33 for (i = 0; i < AC_NUM; i++)
39 int create_ac_socket(unsigned int ac)
41 struct sockaddr_in my_addr;
43 unsigned int yes=1, tos;
46 if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
48 perror("Socket nelze otevrit");
52 if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
53 perror("Chyba v nastaveni soketu");
57 if (opt_same_interface) {
59 if (setsockopt(sockfd, SOL_IP, IP_PKTINFO, &receive, sizeof(receive)) == -1) {
60 perror("setsockopt: IP_PKTINFO");
66 // bzero(&my_addr, sizeof(my_addr));
67 memset(&my_addr,0, sizeof(my_addr));
68 my_addr.sin_family = AF_INET;
69 my_addr.sin_addr.s_addr = INADDR_ANY;
70 my_addr.sin_port = htons(BASE_PORT + ac);
72 if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1) {
73 perror("Chyba v bind");
78 //tos = ((AC_NUM - ac) *2 - 1)*32;
80 if (setsockopt(sockfd, SOL_IP, IP_TOS, &tos, sizeof(tos))) {
81 perror("Unable to set TOS");
89 void* qhandler(void* queue)
92 struct sockaddr_in rem_addr;
94 unsigned int rem_addr_length;
96 char cbufrec[512], cbufsend[512];
99 struct in_pktinfo *ipi = NULL;
102 ac = (intptr_t) queue;
103 rem_addr_length=sizeof(rem_addr);
109 struct cmsghdr *cmsg;
111 iov.iov_base = &buff;
112 iov.iov_len = sizeof(buff);
113 msg.msg_name = (void*)&rem_addr;
114 msg.msg_namelen = sizeof(rem_addr);
118 msg.msg_control = cbufrec;
119 msg.msg_controllen = sizeof(cbufrec);
121 while ((mlen = recvmsg(ac_sockfd[ac], &msg, 0)) < 0) {
122 if (errno == EINTR) continue;
126 clock_gettime(CLOCK_REALTIME, &ts);
127 buff.msg.sendback_timestamp = ts.tv_sec*1000000000 + ts.tv_nsec;
130 if (opt_same_interface) {
131 /* determine receiving interface */
132 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
133 if (cmsg->cmsg_level == SOL_IP) {
134 if (cmsg->cmsg_type == IP_PKTINFO) {
135 /* char spec_dst[20], addr[20]; */
136 ipi = (struct in_pktinfo*)CMSG_DATA(cmsg);
137 if (cmsg->cmsg_len <= sizeof(cbufsend)) {
138 struct in_pktinfo *ipi2;
139 msg.msg_control = cbufsend;
140 msg.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
141 cmsg = CMSG_FIRSTHDR(&msg);
142 cmsg->cmsg_level = SOL_IP;
143 cmsg->cmsg_type = IP_PKTINFO;
144 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
145 /* Initialize the payload: */
146 ipi2 = (struct in_pktinfo*)CMSG_DATA(cmsg);
147 memset(ipi2, 0, sizeof(*ipi2));
148 ipi2->ipi_ifindex = ipi->ipi_ifindex;
151 fprintf(stderr, "cbufsend too small\n");
152 msg.msg_control = NULL;
153 msg.msg_controllen = 0;
155 /* strncpy(spec_dst, inet_ntoa(ipi->ipi_spec_dst), sizeof(spec_dst)-1); */
156 /* strncpy(addr, inet_ntoa(ipi->ipi_addr), sizeof(addr)-1); */
157 /* printf("pktinfo if=%d %s %s\n", ipi->ipi_ifindex, spec_dst, addr); */
162 msg.msg_control = NULL;
163 msg.msg_controllen = 0;
169 receivers[ac].received++;
170 msg.msg_iov->iov_len = mlen;
172 /* resp_port is already stored in network order */
173 rem_addr.sin_port = buff.msg.resp_port;
175 while (sendmsg(ac_sockfd[ac], &msg, 0) < 0) {
176 if (errno == EINTR) continue;
184 int main(int argc, char *argv[])
194 while ((opt = getopt(argc, argv, "I")) != -1) {
197 opt_same_interface = true;
200 fprintf(stderr, "Usage: %s [ options ]\n\n", argv[0]);
201 fprintf(stderr, "Options:\n");
202 fprintf(stderr, " -I send back through the same interface (bypass routing tables)\n");
206 pthread_attr_init(&attr);
208 if (signal(SIGTERM, stopper) == SIG_ERR) {
209 perror("Signal handler registration error");
213 if (signal(SIGINT, stopper) == SIG_ERR) {
214 perror("Signal handler registration error");
218 for (ac = 0; ac < AC_NUM; ac++) {
219 ac_sockfd[ac] = create_ac_socket(ac);
220 rc = pthread_create(&thread, &attr, qhandler, (void*) ac);
226 for (ac = 0; ac < AC_NUM; ac++) {
227 int delta = receivers[ac].received - receivers[ac].last_received;
228 receivers[ac].last_received = receivers[ac].received;
229 fprintf(stderr, "%s %5d %4d/s ", ac_to_text[ac], receivers[ac].received, delta);