Beispiel #1
0
Boolean Groupsock::handleRead(unsigned char* buffer, unsigned bufferMaxSize,
			      unsigned& bytesRead,
			      struct sockaddr_in& fromAddress) {
  // Read data from the socket, and relay it across any attached tunnels
  //##### later make this code more general - independent of tunnels

  bytesRead = 0;

  int maxBytesToRead = bufferMaxSize - TunnelEncapsulationTrailerMaxSize;
  int numBytes = readSocket(env(), socketNum(),
			    buffer, maxBytesToRead, fromAddress);
  if (numBytes < 0) {
    if (DebugLevel >= 0) { // this is a fatal error
      env().setResultMsg("Groupsock read failed: ",
			 env().getResultMsg());
    }
    return False;
  }

  // If we're a SSM group, make sure the source address matches:
  if (isSSM()
      && fromAddress.sin_addr.s_addr != sourceFilterAddress().s_addr) {
    return True;
  }

  // We'll handle this data.
  // Also write it (with the encapsulation trailer) to each member,
  // unless the packet was originally sent by us to begin with.
  bytesRead = numBytes;

  int numMembers = 0;
  if (!wasLoopedBackFromUs(env(), fromAddress)) {
    statsIncoming.countPacket(numBytes);
    statsGroupIncoming.countPacket(numBytes);
    numMembers =
      outputToAllMembersExcept(NULL, ttl(),
			       buffer, bytesRead,
			       fromAddress.sin_addr.s_addr);
    if (numMembers > 0) {
      statsRelayedIncoming.countPacket(numBytes);
      statsGroupRelayedIncoming.countPacket(numBytes);
    }
  }
  if (DebugLevel >= 3) {
    env() << *this << ": read " << bytesRead << " bytes from ";
    env() << our_inet_ntoa(fromAddress.sin_addr);
    if (numMembers > 0) {
      env() << "; relayed to " << numMembers << " members";
    }
    env() << "\n";
  }

  return True;
}
Boolean Groupsock::output(UsageEnvironment& env, u_int8_t ttlToSend,
                          unsigned char* buffer, unsigned bufferSize,
                          DirectedNetInterface* interfaceNotToFwdBackTo) {
    do {
        // First, do the datagram send, to each destination:
        Boolean writeSuccess = True;
        for (destRecord* dests = fDests; dests != NULL; dests = dests->fNext) {
            int res = 0;
            if (!(res = write(dests->fGroupEId.groupAddress().s_addr, dests->fPort, ttlToSend,
                              buffer, bufferSize))) {
                if (-1 == res)
                {
                    fprintf(stderr, "errno = %d, errorsrting = %s\n", strerror(errno));
                }
                writeSuccess = False;
                break;
            }
        }
        if (!writeSuccess) break;
        statsOutgoing.countPacket(bufferSize);
        statsGroupOutgoing.countPacket(bufferSize);

        // Then, forward to our members:
        int numMembers = 0;
        if (!members().IsEmpty()) {
            numMembers =
                outputToAllMembersExcept(interfaceNotToFwdBackTo,
                                         ttlToSend, buffer, bufferSize,
                                         ourIPAddress(env));
            if (numMembers < 0) break;
        }

        if (DebugLevel >= 3) {
            env << *this << ": wrote " << bufferSize << " bytes, ttl "
                << (unsigned)ttlToSend;
            if (numMembers > 0) {
                env << "; relayed to " << numMembers << " members";
            }
            env << "\n";
        }
        return True;
    } while (0);

    if (DebugLevel >= 0) { // this is a fatal error
        env.setResultMsg("Groupsock write failed: ", env.getResultMsg());
    }
    return False;
}
Beispiel #3
0
Boolean Groupsock::output(UsageEnvironment& env, unsigned char* buffer, unsigned bufferSize,
			  DirectedNetInterface* interfaceNotToFwdBackTo) {
  do {
    // First, do the datagram send, to each destination:
    Boolean writeSuccess = True;
    for (destRecord* dests = fDests; dests != NULL; dests = dests->fNext) {
      if (!write(dests->fGroupEId.groupAddress().s_addr, dests->fGroupEId.portNum(), dests->fGroupEId.ttl(),
		 buffer, bufferSize)) {
	writeSuccess = False;
	break;
      }
    }
    if (!writeSuccess) break;
    statsOutgoing.countPacket(bufferSize);
    statsGroupOutgoing.countPacket(bufferSize);

    // Then, forward to our members:
    int numMembers = 0;
    if (!members().IsEmpty()) {
      numMembers =
	outputToAllMembersExcept(interfaceNotToFwdBackTo,
				 ttl(), buffer, bufferSize,
				 ourIPAddress(env));
      if (numMembers < 0) break;
    }

    if (DebugLevel >= 3) {
      env << *this << ": wrote " << bufferSize << " bytes, ttl " << (unsigned)ttl();
      if (numMembers > 0) {
	env << "; relayed to " << numMembers << " members";
      }
      env << "\n";
    }
    return True;
  } while (0);

  if (DebugLevel >= 0) { // this is a fatal error
    UsageEnvironment::MsgString msg = strDup(env.getResultMsg());
    env.setResultMsg("Groupsock write failed: ", msg);
    delete[] (char*)msg;
  }
  return False;
}