void
resolver::sendreq (dnsreq *r)
{
  if (!udpsock) {
    setsock (false);
    return;
  }

  ptr<dnssock> sock;
  if (!r->usetcp)
    sock = udpsock;
  else if (!tcpsock && !tcpinit ()) {
    setsock (true);
    return;
  }
  else
    sock = tcpsock;

  u_char qb[QBSIZE];
  int n;
  n = res_mkquery (QUERY, r->name, C_IN, r->type,
		   NULL, 0, NULL, qb, sizeof (qb));
  //warn ("query (%s, %d): %d\n", r->name.cstr (), r->type, n);
  if (n < 0) {
    r->fail (ARERR_REQINVAL);
    return;
  }

  HEADER *const h = (HEADER *) qb;
  h->id = r->id;
  h->rd = 1;

  /* FreeBSD (and possibly other OSes) have a broken dn_expand
   * function that doesn't properly invert dn_comp.
   */
  {
    dnsparse query (qb, n, false);
    question q;
    if (query.qparse (&q))
      r->name = q.q_name;
  }

  sock->sendpkt (qb, n);
}
bool
resolver::setsock (bool failure)
{
  if (udpcheck_req) {
    delete udpcheck_req;
    udpcheck_req = NULL;
  }

  do {
    if ((failure || !addr) && !bumpsock (failure))
      return false;
    failure = true;
    nbump++;
    last_resp = 0;
    last_bump = timenow;
    tcpsock = NULL;
  } while (!udpinit () || !tcpinit ());

  return resend (true, true);
}
Пример #3
0
int main(void)
{
	struct pollfd sfd[3];
	const long timeout=500; //connection timeout in seconds

	struct timespec ts_timeout;

	int size;

	field *pmessage;

	fldformat *frm;

	isomessage smessage;

	GOOGLE_PROTOBUF_VERIFY_VERSION;

	frm=loadNetFormat();

	if(!frm)
	{
		printf("Error: Can't load format\n");
		return 1;
	}

	printf("Message format loaded\n");

	sfd[2].fd=tcpinit();

	if(sfd[2].fd==-1)
	{
		printf("Error: Unable to start TCP connection\n");
		freeFormat(frm);
		return 1;
	}

	sfd[0].fd=ipcopen((char *)"visa");

	if(sfd[0].fd==-1)
	{
		printf("Error: Unable to connect to switch\n");
		close(sfd[2].fd);
		freeFormat(frm);
		return 1;
	}

	if (signal(SIGINT, catch_sigint) == SIG_ERR)
		printf("Warning: unable to set the signal handler\n");

	sfd[0].events=POLLIN;
	sfd[1].events=POLLIN;

	while (1)
	{
		printf("Waiting for a connection...\n");

		errno=0;
		sfd[1].fd=tcpconnect(sfd[2].fd);
		if(sfd[1].fd==-1)
		{
			if(sigint_caught)
			{
				printf("onnection aborted^\n");
				break;
			}

			printf("Connection error: %s\n", strerror(errno));
			sleep(1);
			continue;
		}

		printf("Connected.\n");

		while (1)
		{
			printf("Waiting for a message...\n");

			ts_timeout.tv_sec=timeout;
			ts_timeout.tv_nsec=0;
			errno=0;

			size=ppoll(sfd, 2, &ts_timeout, NULL);

			//printf("poll: %d: %hd, %hd: %s\n", size, sfd[0].revents, sfd[1].revents, strerror(errno));

			if(size==-1)
			{
				if(sigint_caught)
				{
					printf("losing connection^\n");
					break;
				}

				printf("Error: poll (%hd, %hd): %s\n", sfd[0].revents, sfd[1].revents, strerror(errno));
				if(sfd[1].revents)
					break;
				else
				{
					usleep(100000);
					continue;
				}
			}
			else if(size==0)
			{
				printf("Error: Connection is inactive, closing it %ld, %ld\n", ts_timeout.tv_sec, ts_timeout. tv_nsec);
				break;
			}

			if(sfd[1].revents & POLLIN)
			{
				printf("Receiving message from net\n");

				size=tcprecvmsg(sfd[1].fd, &pmessage, frm);

				if(size==-1)
				{
					printf("Closing connection\n");
					break;
				}
				else if(size==0)
					continue;

				print_message(pmessage);

				if(isNetMgmt(pmessage))
				{
					if(isNetRequest(pmessage))
					{
						if(!processNetMgmt(pmessage))
						{
							printf("Error: Unable to process Network Management request. Message dropped.\n");
							freeField(pmessage);
							continue;
						}

						print_message(pmessage);

						size=tcpsendmsg(sfd[1].fd, pmessage);

						if(size==-1)
						{
							printf("Closing connection\n");
							freeField(pmessage);
							break;
						}
						else if(size==0)
						{
							freeField(pmessage);
							continue;
						}

						printf("Network Management Message sent (%d bytes)\n", size);
					}

					freeField(pmessage);
					continue;
				}

				if(translateNetToSwitch(&smessage, pmessage)!=0)
				{
					printf("Error: Unable to translate the message to format-independent representation.\n");

					if(isNetRequest(pmessage))
					{
						if(!declineNetMsg(pmessage))
						{
							printf("Error: Unable to decline the request. Message dropped.\n");
							freeField(pmessage);
							continue;
						}

						print_message(pmessage);

						size=tcpsendmsg(sfd[1].fd, pmessage);

						if(size==-1)
						{
							printf("Closing connection\n");
							freeField(pmessage);
							break;
						}
						else if(size==0)
						{
							freeField(pmessage);
							continue;
						}

						printf("Decline message sent (%d bytes)\n", size);
					}

					freeField(pmessage);
					continue;
				}

				printf("Converted message:\n");
				smessage.PrintDebugString();

				size=ipcsendmsg(sfd[0].fd, &smessage, (char *)"switch");

				if(size<=0)
				{
					printf("Error: Unable to send the message to switch\n");

					if(isNetRequest(pmessage))
					{
						if(!declineNetMsg(pmessage))
						{
							printf("Error: Unable to decline the request. Message dropped.\n");
							freeField(pmessage);
							continue;
						}

						print_message(pmessage);

						size=tcpsendmsg(sfd[1].fd, pmessage);

						if(size==-1)
						{
							printf("Closing connection\n");
							freeField(pmessage);
							break;
						}
						else if(size==0)
						{
							freeField(pmessage);
							continue;
						}

						printf("Decline message sent (%d bytes)\n", size);
					}

					freeField(pmessage);
					continue;
				}

				freeField(pmessage);

				printf("Message sent, size is %d bytes.\n", size);
			}

			if(sfd[0].revents & POLLIN)
			{
				printf("Receiving message from switch\n");

				if(ipcrecvmsg(sfd[0].fd, &smessage)<0)
					continue;

				printf("\nOutgoingMessage:\n");
		                smessage.PrintDebugString();

				pmessage=translateSwitchToNet(&smessage, frm);

				if(!pmessage)
				{
					printf("Error: Unable to translate the message from format-independent representation.\n");

					if(isRequest(&smessage))
					{
						if(!declineMsg(&smessage))
						{
							printf("Error: Unable to decline the request. Message dropped.\n");
							continue;
						}

						smessage.PrintDebugString();

						size=ipcsendmsg(sfd[0].fd, &smessage, (char *)"switch");

						if(size<=0)
						{
							printf("Error: Unable to return the declined message to switch. Message dropped.\n");
							continue;
						}

						printf("Decline message sent (%d bytes)\n", size);

					}
					continue;
				}

				print_message(pmessage);

				size=tcpsendmsg(sfd[1].fd, pmessage);

				freeField(pmessage);

				if(size==-1)
				{
					printf("Closing connection\n");

					if(isRequest(&smessage))
					{
						if(!declineMsg(&smessage))
						{
							printf("Error: Unable to decline the request. Message dropped.\n");
							continue;
						}

						smessage.PrintDebugString();

						size=ipcsendmsg(sfd[0].fd, &smessage, (char *)"switch");

						if(size<=0)
						{
							printf("Error: Unable to return the declined message to switch. Message dropped.\n");
							continue;
						}

						printf("Decline message sent (%d bytes)\n", size);

					}
					break;
				}
				else if(size==0)
				{
					if(isRequest(&smessage))
					{
						if(!declineMsg(&smessage))
						{
							printf("Error: Unable to decline the request. Message dropped.\n");
							continue;
						}

						smessage.PrintDebugString();

						size=ipcsendmsg(sfd[0].fd, &smessage, (char *)"switch");

						if(size<=0)
						{
							printf("Error: Unable to return the declined message to switch. Message dropped.\n");
							continue;
						}

						printf("Decline message sent (%d bytes)\n", size);
					}
					continue;
				}

				printf("Message sent (%d bytes)\n", size);
			}

		}

		tcpclose(sfd[1].fd);

		printf("Disconnected.\n");

		if(sigint_caught)
			break;
	}

	tcpclose(sfd[2].fd);
	ipcclose(sfd[0].fd);
	freeFormat(frm);
	google::protobuf::ShutdownProtobufLibrary();
	
	return 0;
}