the SO_REUSEPORT option not works on macOS with libuv.
uv_loop_init
uv_tcp_init_ex
uv_fileno // get fd
int option_value = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &option_value, sizeof (int)
uv_tcp_bind
uv_thread_create 4
I see 4 same address and port binding at 0.0.0.0:8080, but only thread1's connection_cb works, so can I use this option with my program? thx.
macOS (and other BSDs) have a different SO_REUSEPORT implementation than Linux. On (relatively) recent Linux versions it will allow you to kernel level load balancing, but on BSDs only the last socket to bind will get the connections.
Long story short, it cannot be made to work, alas.
Related
SO_REUSEPORT is deleted to make the example work on macOS.
Socket programming - setsockopt: Protocol not available?
But man setsockopt on macOS clearly document the option SO_REUSEPORT.
SO_REUSEPORT enables duplicate address and port bindings
Why SO_REUSEPORT has to be removed to make the example? Is there a bug in setsockopt() on macOS? Where is the source code of setsockopt() on macOS?
SO_REUSEPORT is an option for secsockopt, so the source for it is in the kernel proper. That'd be xnu's sources, specifically the sys call handler checks validity (bsd/kern/uipc_socket.c) and the IPv4/v6 stacks
(bsd/netinet/in_pcb.c and bsd/netinet6/in6_pcb.c, respectively) implement it. From it, you can see two things:
that SO_REUSEPORT and SO_REUSEADDR actually work interchangeably in many cases (e.g. multicast).
it would work in the sample you referred to when put in two setsockopt(2) calls, as well: The mistake was that the options are not bitmasks, so | and + won't work with them - even though
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
are used in the kernel as bit masks later on (|'ed) , the code in kernel to handle getsockopt and check for validity uses a switch statement, so it ends up that neither option is honored, because it doesn't fall in those cases. Specifically, it's bsd/kern/uipc_socket.c:
int sosetoptlock(struct socket *so, struct sockopt *sopt, int dolock)
{
. ...
switch (sopt->sopt_name) {
. ..
case SO_REUSEADDR:
case SO_REUSEPORT:
case SO_OOBINLINE:
case SO_TIMESTAMP:
case SO_TIMESTAMP_MONOTONIC:
case SO_TIMESTAMP_CONTINUOUS:
case SO_DONTTRUNC:
case SO_WANTMORE:
case SO_WANTOOBFLAG:
case SO_NOWAKEFROMSLEEP:
case SO_NOAPNFALLBK:
error = sooptcopyin(sopt, &optval, sizeof(optval),
...
On old iMX.6 BSP without DT (Device Tree), GPIO is controlled by following code:
#define SABRESD_SHUTDOWN IMX_GPIO_NR(4, 15)
gpio_request(SABRESD_SHUTDOWN, "shutdown");
gpio_direction_output(SABRESD_SHUTDOWN, 1);
gpio_set_value(SABRESD_SHUTDOWN, 0);
gpio_free(SABRESD_SHUTDOWN);
However on new BSP, I cannot use IMX_GPIO_NR anymore. Instead, of_get_named_gpio provides access to GPIO defined in DT. But it is a little complicated because our product never changes the GPIO ports.
My question is, is it possible to control GPIOs without DT definition (just using the old method)?
First of all, if you are using newer kernel, I would recommend you to port your code to support the latest features. Otherwise - why bothering upgrading the kernel if you are not willing to adapt to it?
Second, never say never.
And finally:
#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr))
I'm trying to send some self-packed Ethernet packets via the Winpcap API pcap_sendpacket(), but I got two identical packets after invoking the API once. The two packets can be captured on Wireshark for debugging purpose, with identical data and continuous frame numbers.
The environment is Win7 64bit. And it is wierd that the same code base running on another Win7 64bit will show only one packet on Wireshark.
Edit:
[2016.1.24 19:30]
I'm sorry I can only post the pcap related code parts due to the confidential thing
// first, enum the device list
pcap_if_t *m_alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs(&m_alldevs, errbuf) == -1)
{
// log error ...
for(pcap_if_t *d = m_alldevs; d != NULL; d = d->next)
{
// second, open the interface
// use flag PCAP_OPENFLAG_MAX_RESPONSIVENESS to get response quickly
// set timeout to 1000ms
errbuf[PCAP_ERRBUF_SIZE];
pcap_t* fp = pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS|PCAP_OPENFLAG_MAX_RESPONSIVENESS, 1000, NULL, errbuf);
// third, get the interface device then release all the device
pcap_freealldevs(m_alldevs);
// 4th, send data
// unsigned char* buf;
// int size;
pcap_sendpacket(fp, buf, size);
And for the packet, the packet is handcrafted, with size between 64 and 1500, has an IEEE 802.3 type frame header, the two mac fields are customized.
On the machine that has the error, the version of the Winpcap is "4.1.0.2980", Wireshark is "64bit 1.12.3"; I will check the other machine that does not have the error tomorrow.
Edit:
[2016.1.26 10:30]
The version of the Winpcap is "4.1.0.2980", the same as on the machine with error. The version of Wireshark is "64bit 1.12.8". Both OS are Win7 Enterprise 64bit.
I had the same problem.
My steps to resolve it:
uninstall winpcap & npcap. I have both on my local machine
install only npcap
use delayed dll loading according to https://nmap.org/npcap/guide/npcap-devguide.html section "For software that want to use Npcap first when Npcap and WinPcap coexist".
I was able to control GPIO using mmap system call to control LED operation directly from the user space. Now I want to implement driver in kernel space.
I am trying to write my first kernel space device driver for 16*2 line of LCD in Linux for ARM controller RPi.
Now i need to access the GPIO for this purpose.
In AVR i use to access the Port like this.
#define PORTA *(volatile unsigned char*)0x30
I was reading LLD it tells to use inb() & outb() function to access the i/o port.
http://www.makelinux.net/ldd3/chp-9-sect-2
1> Can we not use #define address of port to access the GPIO ?
2> What is the advantages to use use inb() & outb() functions for controlling the GPIO ?
Please suggest.
In AVR i use to access the Port like this.
#define PORTA *(volatile unsigned char*)0x30
That's an improper definition that overloads the symbol PORTA.
Besides defining the port address as 0x30, you are also dereferencing that location.
So it is actually a read operation, but there's no indication of that in the name, i.e. you have really defined a macro for READ_PORTA.
1> Can we not use #define address of port to access the GPIO ?
Of course you can (and should).
#define PORTA (unsigned char *)0x30
You'll find similar statements in header files for device registers in the Linux source tree. When developing a new device driver, I look for a header file of #defines for all of the device's registers and command codes, and start writing one if no file is already available.
2> What is the advantages to use use inb() & outb() functions for controlling the GPIO ?
The code is then an unambiguous statement that I/O is being performed, regardless of whether the architecture uses I/O ports or memory-mapped I/O.
Anyone reading the following should be able to deduce what is going on:
x = inb(PORTA);
versus the confusion when using your macro:
x = PORTA;
The above statement using an overloaded macro would not pass a code review conducted by competent coders.
You should also get familiar with and use the Linux kernel coding style.
1) the use of defines simplifies your task often. You could, of course, not use define for your port and use this construction literally everywhere you need to access the port. But then you will have to replace the 0x30 everywhere with another address if you change the design of your device, for example, if you decide to connect your LED to port B. Also, it will make your code less readable. Alternatively you could declare a function that will access your port. If such a simple function is declared inline (if your compiler supports inlines) then there is no difference in performance.
2) the advantage of using inb() and outb() is portability of your program. If this is not an issue, then it is fine to access your port directly.
I have been using Unimotion in my application to read motion sensor values for Apple laptops, but have been unable to port the code to 10.6 64-bit. (I have also tried SMSLib and had the no luck either.)
Is there any simple 10.6 compatible
SMS API?
If there is no alternative, I am also considering patching one of the libraries. Both Unimotion and SMSLib use the following call, which has been deprecated in 10.5 and removed from 10.6 64-bit:
result = IOConnectMethodStructureIStructureO(
dataPort, kernFunc, structureInputSize,
&structureOutputSize, &inputStructure,
outputStructure);
Is there any simple way to replace
this with new IOKit calls?
(This post did not really get me much further)
If there is no alternative, I am also considering patching one of the libraries. Both Unimotion and SMSLib use the following call, which has been deprecated in 10.5 and removed from 10.6 64-bit:
result = IOConnectMethodStructureIStructureO(
dataPort, kernFunc, structureInputSize,
&structureOutputSize, &inputStructure,
outputStructure);
Is there any simple way to replace this with new IOKit calls?
That very document suggests replacements. What about this one?
kern_return_t
IOConnectCallStructMethod(
mach_port_t connection, // In
uint32_t selector, // In
const void *inputStruct, // In
size_t inputStructCnt, // In
void *outputStruct, // Out
size_t *outputStructCnt) // In/Out
As far as I can tell, there should be no difference except for the order of the arguments. That said, I've never used I/O Kit, so I could be missing some critical conceptual difference that will make this call not work as the old one did.
I haven't used this in 10.6, but does this work?
http://code.google.com/p/google-mac-qtz-patches/