On Thu, 26 Feb 2009, Rainer Gerhards wrote: > Hi David, > > I think you got lost in the callbacks.
yep, that's what I meant by the 'twisty maze of helper functions' > The multiple send calls are not for multiple actions. This is all for > one action. That code was contributed as part of the IPv6 port. I > verified the implementation with what I could find as references to > sending on IPv6 and think the implementation uses proper procedures for > that environment. > > In essence, on an IPv6-enabled system, you will receive multiple sockets > that you potentially can use to send the message. What the code does is > iterate over these sockets and see which one really works. There is also > an option (not checked but pretty sure) that permits sending to all > receivers. I think that was the other situation you have seen. this I definantly don't understand. I haven't done much coding in this area, and most of what I have done ends up being cut-n-paste out of the 'linux application programming' book examples (which are supposed to work for IPv6 as well as v4) > The listen socket is NOT being reused for sending. when I chased down the callback functions to find what function created the sockets, the only thing that I found was a routine that looked like it was going through the config options to create sockets for all the listening ports. > RFC3164 actually > recommends that port 514 is used as the source port, and we had a > lengthy discussion at the IETF about this recommendation. The bottom > line is that you cannot reuse the receive socket on a highly parallel > syslogd because each thread needs its own (or you have even more sync). > Rsyslog creates a new (set of) send sockets *per action*. if you don't do a bind on the socket you can't specify the source port. if you do bind on the socket and set the source port to 514 aren't you generating a conflict between the multiple send sockets? > I guess part of the confusion stems back from your understanding of > sysklogd code. Sysklogd works totally different here. probably. > I hope this clarifies a bit. I will try to have a look at the code > provided asap and see what I can do. Its unfortunately still very busy, > so I can not commit when I will finally start. thanks. I'll keep poking at this. David Lang > HTH > Rainer > >> -----Original Message----- >> From: [email protected] [mailto:rsyslog- >> [email protected]] On Behalf Of [email protected] >> Sent: Wednesday, February 25, 2009 9:47 PM >> To: rsyslog-users >> Subject: Re: [rsyslog] UDP source forging. >> >> figuring out how to do this is navigating a twisty maze of helper >> functions, all different ;-) >> >> there are a few things that look odd here if I am reading the code >> properly. >> >> rsyslog makes one call to the UDPSend routine for all forwarded >> messages, >> this means that they must all send the same format. >> >> the UDPSend routine then walks through all destinations attempting to >> send >> the message to them. and considers the message successfully sent if > any >> of >> them can be sent. I would have expected that it would only be >> considered >> successful if all of them succeded. >> >> UDPSend attempts to use the sockets that were created to listening for >> messages to send it's message out. in a multi-homed machine the local >> IP >> address of those sockets may not be appropriate for the relay. also, >> what >> would happen if a system recieves via TCP and forwards via UDP and so >> doesn't have any UDP listener sockets. >> >> >> so now, my suggestion >> >> On Linux in /etc/sysctl.conf add the line >> >> net.ipv4.ip_nonlocal_bind=1 >> >> this tells the kernel not to fail bind requests to IP addresses that >> don't >> exist on the box >> >> then in omfwd.c >> >> in the routine that calls UDPSend, modify it to pass the source IP >> address >> of the message to UDPSend >> >> create a new filehandle array to use for outbound messages (one >> filehandle >> for each destination since they may end up with different source IPs) >> >> >> in UDPSend >> >> three options. >> >> >> 1. default >> >> use the appropriate filehandle for each destination and send the >> message. this is similar to what currently takes place, but instead of >> walking through each open socket for each destination, there should >> only >> be one sendto per destination. when opening the socket it should not > be >> nessasary to do a bind, just issue the socket call. >> >> if there is anything in the syslog standard specifying the source >> port >> (I don't think there is, although many implementations use port 514 >> becouse they do the same thing that rsyslog is doing and re-use >> listening >> sockets to send messages) >> >> >> 2. randomize source ports to support external load balancers >> >> same as default, except that every X (configurable) messages close >> and >> re-open the sockets. >> >> the reason for this is that each time a message is first sent the > OS >> picks a random source port that will be used for all messages sent >> through >> that socket. by closing the socket once in a while, load balancers > that >> balance based on source IP + source port + destination IP + > destination >> port will be able to function (a similar feature for TCP based >> transports >> would be useful for the same reason) >> >> >> 3. forge the source IP/port >> >> for each message that is sent, open a new socket, then issue a >> 'bind' >> command for that socket (filehandle) that sets the local IP address to >> the >> IP address that the message initially came from, then issue the > sendto, >> then close the filehandle. >> >> there is no need for an array of sockets in this case as the socket >> needs to be re-opened for each message/destination. in theory there is >> a >> possibility of a performance gain by keeping sockets open and re-using >> them, but since each socket is unique to the sender + destination > there >> would be a large number of sockets and a low probability of re-using a >> socket for the next message. >> >> in sysklogd I implemented #2 with the simple code below (once I > created >> a >> different filehandle to use for outbound connections) >> >> this closed and re-opened the socket for each message, doing it every > X >> messages would save on the overhead and be just as good in practice. >> >> the bind command that's commented out is basicly what would be needed >> for >> #3, but with real values for the source.sin_addr.s_addr (and >> source.sin_port if you wanted to forge the port as well, leaving it >> zero >> lets the OS pick a port number) >> >> if (finet >0) { >> /* close and re-open the outbound socket after each message > so >> that the source port is randomized and load balancers can distribute >> the messages */ >> close(finet); >> finet = create_inet_socket(); >> /* if we want to forge the source IP for the outbound > packets, >> this is the place to do it by seeting the IP address to the address we >> received the message from >> struct sockaddr_in source; >> source.sin_addr.s_addr = 0x00000000; >> source.sin_port = 0x0000; >> bind(finet,(struct sockaddr *) >> &source,sizeof(source));*/ >> } >> >> >> the create_inet_socket() routine is: >> >> static int create_inet_socket() >> { >> int fd, on = 1; >> int sockflags; >> >> fd = socket(AF_INET, SOCK_DGRAM, 0); >> if (fd < 0) { >> logerror("syslog: Unknown protocol, suspending inet >> service."); >> return fd; >> } >> >> if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, \ >> (char *) &on, sizeof(on)) < 0 ) { >> logerror("setsockopt(REUSEADDR), suspending inet"); >> close(fd); >> return -1; >> } >> /* We must not block on the network socket, in case a packet >> * gets lost between select and recv, otherise the process >> * will stall until the timeout, and other processes trying > to >> * log will also stall. >> */ >> if ((sockflags = fcntl(fd, F_GETFL)) != -1) { >> sockflags |= O_NONBLOCK; >> /* >> * SETFL could fail too, so get it caught by the >> subsequent >> * error check. >> */ >> sockflags = fcntl(fd, F_SETFL, sockflags); >> } >> if (sockflags == -1) { >> logerror("fcntl(O_NONBLOCK), suspending inet"); >> close(fd); >> return -1; >> } >> return fd; >> } >> >> >> this isn't a patch like you asked for and I offered to put togeather, >> but >> is it enough to clearly explain this? if not I can continue to work on >> the >> patch. >> >> David Lang >> >> On Tue, 24 Feb 2009, Rainer Gerhards wrote: >> >>> David, >>> >>> Excellent, please do as you have time. I'll make sure it fits. >>> Thread-safety, btw., is not a big issue at this level as the output >>> modules are guaranteed to be never called by multiple threads >>> concurrently. That was a trade-off to enable other folks to easily >> write >>> them (but I have an option in the back of my head that a module can >> tell >>> the engine it *is* capable to run on multiple threads >> concurrently...). >>> >>> Rainer >>> >>>> -----Original Message----- >>>> From: [email protected] [mailto:rsyslog- >>>> [email protected]] On Behalf Of [email protected] >>>> Sent: Tuesday, February 24, 2009 9:43 AM >>>> To: rsyslog-users >>>> Subject: Re: [rsyslog] UDP source forging. >>>> >>>> On Tue, 24 Feb 2009, Rainer Gerhards wrote: >>>> >>>>> Hi David et all, >>>>> >>>>> Currently rsyslog does not support this and I have to admit I was >>>> always >>>>> very hesitant to add it (I see potential for misuse). Co- >>>> incidentally, I >>>>> received a similar request and was about to relay it to the > mailing >>>> list >>>>> to gather feedback. As it looks, this no longer is necessary ;) >>>>> >>>>> When I thought about implementation, I originally thought about > raw >>>>> sockets (which indeed require root access), but if there is any >>> other >>>>> way, I would be most interested. If you can provide some code, I >>> will >>>>> happily integrate it. I think an addition to the omfwd module, in >>> udp >>>>> forwarding, together with a new directive > ($SpoofOriginalUDPAddress >>>> or >>>>> so...) would be the right way to go. >>>> >>>> I'll see about hacking in some example code (probably without any >>>> config >>>> option and not thread-safe) and send it to you. >>>> >>>> there's another similar change in the same area that I was looking >> at, >>>> I'll mock it up as well. >>>> >>>> David Lang >>>> >>>>> Rainer >>>>> >>>>>> -----Original Message----- >>>>>> From: [email protected] >>>>>> [mailto:[email protected]] On Behalf Of >>>> [email protected] >>>>>> Sent: Tuesday, February 24, 2009 4:40 AM >>>>>> To: rsyslog-users >>>>>> Subject: Re: [rsyslog] UDP source forging. >>>>>> >>>>>> On Mon, 23 Feb 2009, RB wrote: >>>>>> >>>>>>> On Mon, Feb 23, 2009 at 18:11, <[email protected]> wrote: >>>>>>>> I have a need to use some products that are stupid enough >>>>>> to ignore the >>>>>>>> host field in the syslog message and instead base >>>>>> everything on the IP >>>>>>>> address the message originates from. >>>>>>>> >>>>>>>> some other syslog servers can handle this by forging the >>>>>> source of the UDP >>>>>>>> packet, can rsyslog do this? >>>>>>> >>>>>>> So is rsyslog originating the messages, or are you using it to >>>>>>> aggregate them and then feed them on to the other [bad] >>>>>> acceptors? I >>>>>>> am unaware of a way to get rsyslog to forge packets (short >>>>>> of writing >>>>>>> an output module), but unless you must get another syslog >>>>>> daemon into >>>>>>> the mix, you may be better off just feeding your messages >>>>>> directly to >>>>>>> the other collector. >>>>>> >>>>>> rsyslog would be the relay from one non-routed network to another >>>>>> non-routed network. >>>>>> >>>>>> this could be a fairly simple change to the UDP output module >>>>>> (adding a >>>>>> couple commands around the sending of a message), but before >>>>>> I dove in to >>>>>> do that I wanted to see if I had missed this feature anywhere. >>>>>> >>>>>> David Lang >>>>>> _______________________________________________ >>>>>> rsyslog mailing list >>>>>> http://lists.adiscon.net/mailman/listinfo/rsyslog >>>>>> http://www.rsyslog.com >>>>>> >>>>> _______________________________________________ >>>>> rsyslog mailing list >>>>> http://lists.adiscon.net/mailman/listinfo/rsyslog >>>>> http://www.rsyslog.com >>>>> >>>> _______________________________________________ >>>> rsyslog mailing list >>>> http://lists.adiscon.net/mailman/listinfo/rsyslog >>>> http://www.rsyslog.com >>> _______________________________________________ >>> rsyslog mailing list >>> http://lists.adiscon.net/mailman/listinfo/rsyslog >>> http://www.rsyslog.com >>> >> _______________________________________________ >> rsyslog mailing list >> http://lists.adiscon.net/mailman/listinfo/rsyslog >> http://www.rsyslog.com > _______________________________________________ > rsyslog mailing list > http://lists.adiscon.net/mailman/listinfo/rsyslog > http://www.rsyslog.com > _______________________________________________ rsyslog mailing list http://lists.adiscon.net/mailman/listinfo/rsyslog http://www.rsyslog.com

