gvanem / watt-32 Goto Github PK
View Code? Open in Web Editor NEWThis project forked from sezero/watt32
Watt-32 TCP/IP library and samples.
Home Page: https://www.watt-32.net/
This project forked from sezero/watt32
Watt-32 TCP/IP library and samples.
Home Page: https://www.watt-32.net/
Dear Watt32,
I've just built the release from the website on Windows, using Open Watcom 1.9. I ran into some problems with winadinf.[hc], and "hacked" them to to compile by adding several #ifdef __WATCOMC__
guards.
I've already seen similar guards in those files, and can provide a diff, or even a pull request. It is however, completely untested at the time of this writing.
Is such a patch welcome? Since I'm not sure what any of the code in the files is supposed to do, I thought to ask first.
For the record, I just followed the directions and did
cd src
configur.bat watcom
wmake -f watcom_w.mak
as the build process.
Hi,
I am trying to correct WATCOM tools support, because it is broken by several incostistencies as calling conventions etc.
There is several macros which purpose is unclear to me and I am not able to properly fix code/make files
DOSX it looks like the main macro to define target
including 32-bit and 64-bit Windows targets
WIN32 unclear purpose
_WIN32 generaly it is used for Windows header files to define WIN32 API
but sometimes it is undefined for some unknown reason and totaly confuse building
__MSDOS__ unclear purpose
Please could you explain me purpose of these macros and relation each to other
I think _WIN32
and __MSDOS__
macros are internal header macros specific for some compilers that should not be undefined or defined or used for other purpose
I think DOSX
macro should do what is necessary without using other macros
Watt32s getpeername()
will return an error if called after a TCP session has been reset by the remote peer. The application will not be able to access information about the connection that just closed. This is contrary to Linux and Winsock where getpeername()
will continue to return successfully until an explicit close()
/closesocket()
is called.
Sample code to reproduce:
/* Compile for DOS4G (Open Watcom) with
* `WCC386 -3 -bt=dos -dWATT32=1 -i=INC -mf ECHOTEST` then
* `WLINK SYS dos4g LIBF LIB\WATTCPWF.LIB F ECHOTEST`
*
* Compile for Linux with
* `gcc echotest.c`
*
* Use `nc 127.0.0.1 12345` on a Linux machine to connect
* then SIGINT (Ctrl + C) nc to initate a TCP RST from the client
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#ifdef WATT32
#include <tcp.h>
#endif
#define PORT 12345
#define BUFFER_SIZE 1024
void print_socket_info(int client_socket, const char* action) {
struct sockaddr_in client_info;
socklen_t client_info_len = sizeof(client_info);
if (getpeername(client_socket, (struct sockaddr*)&client_info, &client_info_len) == 0)
printf("%s: %s:%d\n", action, inet_ntoa(client_info.sin_addr), htons(client_info.sin_port));
else
printf("%s: was socket %d (unfortunetly that's all we know)\n", action, client_socket);
}
void handle_client(int client_socket) {
char buffer[BUFFER_SIZE];
int bytes_received;
while (1) {
bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
if (bytes_received == -1) {
print_socket_info(client_socket, "Error receiving data");
break;
}
else if (bytes_received == 0) {
print_socket_info(client_socket, "Connection closed by client");
break;
}
else {
send(client_socket, buffer, bytes_received, 0);
print_socket_info(client_socket, "Echoed data back to client");
}
}
}
int main() {
int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
#ifdef WATT32
sock_init();
#endif
if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Error creating socket");
exit(EXIT_FAILURE);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET,
server_addr.sin_addr.s_addr = INADDR_ANY,
server_addr.sin_port = htons(PORT);
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("Error binding socket");
exit(EXIT_FAILURE);
}
if (listen(server_socket, 5) == -1) {
perror("Error listening for connections");
exit(EXIT_FAILURE);
}
#ifdef WATT32
client_addr.sin_addr.s_addr = htonl(my_ip_addr);
printf("Server listening on %s:%d...\n", inet_ntoa(client_addr.sin_addr), PORT);
#else
printf("Server listening on port %d...\n", PORT);
#endif
while (1) {
if ((client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &client_len)) == -1) {
perror("Error accepting connection");
continue;
}
print_socket_info(client_socket, "Accepted connection");
handle_client(client_socket);
close(client_socket);
}
close(server_socket);
return 0;
}
Function: static void W32_CALL dhcp_fsm (void) in src/pcdhcp.c starts
with the following code line:
printf ("In %s(): send_timeout: %lu, state: %s\n",
FUNCTION, DWORD_CAST(send_timeout), state_name());
This continuosly produces output similar to this:
In dhcp_fsm(): send_timeout: 4294967295, state: INIT
In dhcp_fsm(): send_timeout: 1052655823, state: SELECTING
In dhcp_fsm(): send_timeout: 1052646076, state: REQUESTING
In dhcp_fsm(): send_timeout: 1052652865, state: REQUESTING
corrupting the application's output. I guess that this a bug and
not a feature or am I missing something?
Regards,
Juan M. Guerrero
Hello,
We've been using WATTCP for years in some DJGPP DOS applications, but I have noticed that UDP DGRAM fragments are sent as EWOULDBLOCK. This is a problem for old games like Quake 2 where sometimes this stupidity does happen, and we can't send them broken up on the server side because it breaks some client parsing. Unfortunately, some of these engines relied on the routers to take care of the problem.
I did some simple test by removing the DGRAM check in check_non_block_tx() but it appears WATTCP just ends up doing the same thing behind the scenes (i.e. breaking up the sendto()s to be less than MAX_MTU - overhead) and the same problem happens.
It would be great if there was a jumbo frames option to just send the whole thing unfragmented and it's up to the clients router to take care of it.
Thanks for all your hard work over the years, we've really gotten a lot of great use out of the library.
Frank
I just tried compiling my C++ code with Watt-32 in the include path, and find that it breaks due to an empty macro called cdecl
. This name is also used for [[gnu::cdecl]]
(or __attribute__((cdecl))
). I'd like to distribute Watt-32 as part of build-gcc, but I expect this will break a lot of code, not just my own.
I think it's very unusual to have a lowercase macro, especially for such a common keyword. Is it possible to rename it to something uppercase, eg. ATTR_CDECL
, or even just CDECL
? I see it's only used in two headers, sys/cdefs.h
and sys/swap.h
.
Hi there - how do I compile on linux?
./configur.sh
doesn't seem to generate the *.err
files as noted in the the header of configur
Is this only something that can be built on windows?
edit:
it just occurred to me that the main reason why I'm even going down this path is because the latest binary version of watt32
available on the website is 2.2
from 2018
I'm trying to compile OpenSSL (3.x)
for use with djgpp
and it seems to be missing a definition for SHUT_RD
which
sys/socket.h
on master in this repository.I should be able to compile OpenSSL
correctly if given a new binary version.
n.b.:
the artifacts that were available on appveyor are not available currently as they are over one month old
Hi,
Just ran into this strange error:
#include <stddef.h>
#include <poll.h>
int main()
{
return poll(NULL, 0, 0);
}
Compiled as C++:
$ i386-pc-msdosdjgpp-g++ test.c -lwatt
/usr/lib/gcc/i386-pc-msdosdjgpp/12.2.0/../../../../i386-pc-msdosdjgpp/bin/ld: /tmp/ccwlbj7Q.o:test.c:(.text+0x1b): undefined reference to `poll(pollfd*, int, int)'
collect2: error: ld returned 1 exit status
But it links correctly when compiled as C.
I'm building libstdc++ with Watt-32 in order to enable the C++ Networking TS, which will likely be standardized at some point (there is some stuff in <experimental/net>
already but I don't believe it's complete yet).
The build completes with no errors but configure fails to define macro _GLIBCXX_HAVE_NETINET_TCP_H
. In the logs I find the following:
configure:76163: checking netinet/tcp.h usability
configure:76163: /home/jw/build-gcc/script/destdir-hack.sh /home/jw/watt32-test/i386-pc-msdosdjgpp /home/jw/build-gcc/build/djcross-gcc-10.3.0/djcross/./gcc/xgcc -B/home/jw/build-gcc/build/djcross-gcc-10.3.0/djcross/./gcc/ -B/home/jw/watt32-test/i386-pc-msdosdjgpp/bin/ -B/home/jw/watt32-test/i386-pc-msdosdjgpp/lib/ -isystem /home/jw/watt32-test/i386-pc-msdosdjgpp/include -isystem /home/jw/watt32-test/i386-pc-msdosdjgpp/sys-include -c -g -O2 conftest.c >&5
In file included from conftest.c:146:
/home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/netinet/tcp.h:41:9: error: unknown type name 'u_long'
41 | typedef u_long tcp_seq;
| ^~~~~~
/home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/netinet/tcp.h:42:9: error: unknown type name 'u_long'
42 | typedef u_long tcp_cc; /* connection count per rfc1644 */
| ^~~~~~
In file included from /home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/netinet/tcp.h:46,
from conftest.c:146:
/home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/sys/pack_on.h: In function 'W32_CLANG_PACK_WARN_OFF':
/home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/sys/pack_on.h:60:13: error: expected declaration specifiers before '#pragma'
60 | #pragma pack(push,1)
| ^~~~
In file included from conftest.c:146:
/home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/netinet/tcp.h:71:2: error: expected declaration specifiers before ';' token
71 | };
| ^
In file included from /home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/netinet/tcp.h:73,
from conftest.c:146:
/home/jw/watt32-test/i386-pc-msdosdjgpp/watt/inc/sys/pack_off.h:64:13: error: expected declaration specifiers before '#pragma'
64 | #pragma pack(pop)
| ^~~~
I suppose netinet/tcp.h
should include sys/wtypes.h
and sys/cdefs.h
?
Hi,
While working on the recent PRs I noticed there could be some room for optimization. I'm looking into that now but I had some questions:
Callbacks from the native to BSD layer have to iterate over the socket list and find the appropriate BSD socket. Seems it would be better to store a pointer from the native socket back to the BSD socket that owns it. But maybe there is some reason why you hadn't done that?
I do see for the ICMP callback:
Line 1845 in 70d84f2
Is that still true? I don't see how it's possible. One BSD socket can only "own" one native socket, no?
I did see you had the idea once to store the Socket*
s in a hash table. I finished the implementation for it now, but as long as there is so much iterating going on, it wouldn't be any faster.
Also I was looking into optimizing select_s()
/poll()
. I see select_s()
has code to check DOS FDs too, but currently it will skip those and set errno = ENOTSOCK
. So which is it? Should select_s()
be able to work with DOS FDs? It would simplify things a bit if it didn't.
Edit: didn't see the check for SK_FIRST
. So stdin/stdout/stderr should be allowed.
In the process of working on #114 I noticed when running configur.bat watcom
the script prints the following message
Generating Watcom makefiles, directories, errnos and dependencies
Run wmake to make target(s):
E.g. "wmake -h -f watcom_s.mak" for small model (16-bit)
"wmake -h -f watcom_l.mak" for large model (16-bit)
"wmake -h -f watcom_3.mak" for small model (32-bit DOS4GW)
"wmake -h -f watcom_f.mak" for flat model (DOS4GW)
"wmake -h -f watcom_x.mak" for flat model (X32VM)
"wmake -h -f watcom_w.mak" for Win32
and both watcom_f.mak
and watcom_x.mak
are generated however, the files are 100% identical
$ md5sum WATCOM_F.MAK WATCOM_X.MAK
0470eaefb49401a55bac1684235e2001 WATCOM_F.MAK
0470eaefb49401a55bac1684235e2001 WATCOM_X.MAK
Is this a redundant file?
I have a big problem with tools like MKMAKE etc, that they are GNU centric and use GNU stupidity with tab character on begining of line.
Do you plan to use some other tools then GNU which are working without dependency on leading tab character?
Tried building with gcc 14 today. It produces some new warnings, mostly bogus (swapped calloc()
arguments). But this one looks valid:
i386-pc-msdosdjgpp-gcc @build/djgpp/gcc.arg -o build/djgpp/get_ip.o get_ip.c
get_ip.c: In function 'freehostent':
get_ip.c:252:36: warning: pointer 'p' used after 'free' [-Wuse-after-free]
252 | for (p = he->h_addr_list[0]; p; p++)
| ~^~
get_ip.c:253:7: note: call to 'free' here
253 | free (p);
| ^~~~~~~~
get_ip.c:255:34: warning: pointer 'p' used after 'free' [-Wuse-after-free]
255 | for (p = he->h_aliases[0]; p; p++)
| ~^~
get_ip.c:256:7: note: call to 'free' here
256 | free (p);
| ^~~~~~~~
I think this should be:
--- a/src/get_ip.c
+++ b/src/get_ip.c
@@ -240,7 +240,7 @@ ret_copy:
void W32_CALL freehostent (struct hostent *he)
{
- char *p;
+ char **p;
SOCK_DEBUGF (("\nfreehostent: %s ", he->h_name));
@@ -249,11 +249,11 @@ void W32_CALL freehostent (struct hostent *he)
DO_FREE (he->h_name);
- for (p = he->h_addr_list[0]; p; p++)
- free (p);
+ for (p = he->h_addr_list; *p; p++)
+ free (*p);
- for (p = he->h_aliases[0]; p; p++)
- free (p);
+ for (p = he->h_aliases; *p; p++)
+ free (*p);
free (he->h_aliases);
free (he->h_addr_list);
Please setup executable attribute for src/configur.sh file and submit this cange to repository.
There is missing this attribute that can not be run on Linux without local manual change.
This happens when the current master branch is compiled under a 16-bit real mode DOS target (watcom build, large memory model). I did not test other targets.
After calling sock_init(), WATT-32 prints out the usual "Configuring through DHCP.." message, and stays there. It never succeeds, and never timeouts - I have to reboot my PC. If executed with a static IP configuration, then the stack works fine. If I link my application against the older WATT-32 2.2 rel 10, then DHCP works fine.
There are, I think, two distinct problems here:
When USE_BSD_API
is defined for a 16-bit DOS with Open Watcom build (wmake -h -f watcom_l.mak
). The following warnings appear:
ioctl.c(99): Warning! W135: Shift amount too large
ioctl.c(128): Warning! W135: Shift amount too large
ioctl.c(285): Warning! W135: Shift amount too large
ioctl.c(286): Warning! W135: Shift amount too large
ioctl.c(287): Warning! W135: Shift amount too large
ioctl.c(290): Warning! W135: Shift amount too large
ioctl.c(291): Warning! W135: Shift amount too large
ioctl.c(316): Warning! W135: Shift amount too large
ioctl.c(325): Warning! W135: Shift amount too large
ioctl.c(348): Warning! W135: Shift amount too large
ioctl.c(349): Warning! W135: Shift amount too large
ioctl.c(353): Warning! W135: Shift amount too large
ioctl.c(357): Warning! W135: Shift amount too large
ioctl.c(377): Warning! W135: Shift amount too large
ioctl.c(402): Warning! W135: Shift amount too large
ioctl.c(403): Warning! W135: Shift amount too large
ioctl.c(410): Warning! W135: Shift amount too large
ioctl.c(413): Warning! W135: Shift amount too large
ioctl.c(418): Warning! W135: Shift amount too large
ioctl.c(422): Warning! W135: Shift amount too large
ioctl.c(439): Warning! W135: Shift amount too large
ioctl.c(443): Warning! W135: Shift amount too large
ioctl.c(444): Warning! W135: Shift amount too large
ioctl.c(451): Warning! W135: Shift amount too large
ioctl.c(456): Warning! W135: Shift amount too large
ioctl.c(457): Warning! W135: Shift amount too large
ioctl.c(472): Warning! W135: Shift amount too large
ioctl.c(519): Warning! W135: Shift amount too large
ioctl.c(523): Warning! W135: Shift amount too large
ioctl.c(527): Warning! W135: Shift amount too large
ioctl.c(531): Warning! W135: Shift amount too large
ioctl.c(535): Warning! W135: Shift amount too large
ioctl.c(561): Warning! W135: Shift amount too large
ioctl.c(571): Warning! W135: Shift amount too large
ioctl.c(572): Warning! W135: Shift amount too large
ioctl.c(591): Warning! W135: Shift amount too large
ioctl.c(616): Warning! W135: Shift amount too large
ioctl.c(617): Warning! W135: Shift amount too large
ioctl.c(618): Warning! W135: Shift amount too large
ioctl.c(619): Warning! W135: Shift amount too large
ioctl.c(620): Warning! W135: Shift amount too large
ioctl.c(621): Warning! W135: Shift amount too large
ioctl.c(622): Warning! W135: Shift amount too large
ioctl.c(623): Warning! W135: Shift amount too large
ioctl.c(624): Warning! W135: Shift amount too large
ioctl.c(625): Warning! W135: Shift amount too large
ioctl.c(626): Warning! W135: Shift amount too large
ioctl.c(627): Warning! W135: Shift amount too large
ioctl.c(628): Warning! W135: Shift amount too large
ioctl.c(629): Warning! W135: Shift amount too large
ioctl.c(630): Warning! W135: Shift amount too large
ioctl.c(631): Warning! W135: Shift amount too large
ioctl.c(632): Warning! W135: Shift amount too large
ioctl.c(633): Warning! W135: Shift amount too large
ioctl.c(634): Warning! W135: Shift amount too large
ioctl.c(635): Warning! W135: Shift amount too large
ioctl.c(636): Warning! W135: Shift amount too large
ioctl.c(637): Warning! W135: Shift amount too large
ioctl.c(638): Warning! W135: Shift amount too large
ioctl.c(639): Warning! W135: Shift amount too large
ioctl.c(640): Warning! W135: Shift amount too large
ioctl.c(641): Warning! W135: Shift amount too large
ioctl.c(642): Warning! W135: Shift amount too large
ioctl.c(643): Warning! W135: Shift amount too large
ioctl.c(644): Warning! W135: Shift amount too large
ioctl.c(645): Warning! W135: Shift amount too large
ioctl.c(646): Warning! W135: Shift amount too large
ioctl.c(647): Warning! W135: Shift amount too large
ioctl.c(648): Warning! W135: Shift amount too large
ioctl.c(649): Warning! W135: Shift amount too large
ioctl.c(650): Warning! W135: Shift amount too large
ioctl.c(651): Warning! W135: Shift amount too large
ioctl.c(652): Warning! W135: Shift amount too large
ioctl.c(653): Warning! W135: Shift amount too large
ioctl.c(654): Warning! W135: Shift amount too large
ioctl.c(655): Warning! W135: Shift amount too large
These warning haven't caused any trouble in my projects. Creating this issue just to document it in case it's the cause of a bug found in the future
I tried looking everywhere, but I cannot find the license of Watt-32 documented anywhere. What's the license?
I have created a real mode (16-bit) DOS gopher client that uses Watt-32 for networking. It is built with OpenWatcom 1.9 and I am using Watt-32 2.2 rev 10, since the newer rev 11 isn't functioning at all on this prehistoric platform.
The application runs well most of the time, but with some very specific destinations it tends to lock up. After investigations, I found out that the freeze always happens when I call tcp_tick(socket). Further investigations lead me to discover that there is a chain of functions that ends with with a memcpy() call - and it's the memcpy() call that locks up the computer. Here's how it looks:
tcp_tick(s)
_ip_handler()
_tcp_handler()
_tcp_fsm()
tcp_estab_state()
tcp_process_data()
data_in_order()
copy_in_order()
memcpy()
The immediate reason is that memcpy() is performing a buffer overflow, because it is called with a value well outside the internal Watt-32 buffer. I attach a photo of my screen filled with the variety of printf calls that I added when investigating the problem. It shows, at the bottom of the screen, the arguments used by copy_in_order() when performing the memcpy() call.
memcpy is being called with a negative length (-1024) which makes it actually copy 64512 bytes, since memcpy's argument is an unsigned int 16 bits wide.
in tcp_fsm.c I see there is such assumption in data_in_order():
/* Skip data before recv_next. We must be left with some data or
* we wouldn't have been called.
*/
data += diff;
len -= diff;
This assumes that len > diff, while in my case it is not (len = 23, diff = 1047). I have no clue why is that nor I understand what "diff/ldiff" is representing exactly, nonetheless the code appears to be mishandling a condition it is not prepared to handle.
Any pointers about what should I do next please?
For the time being I added a primitive safe guard in tcp_process_data() that makes the function exit whenever len < ldiff (PATCH HERE). This is unlikely to be a solution, it might perhaps corrupt the tcp stream even - I don't know, but at least it doesn't lock up my machine any more. A proper solution should be devised by someone who knows exactly the Watt-32 internals.
The rdtsc timer code ( [edit: 8254 timer (gettod.c
, tsc_microsec()
/adjust_cpu_clock()
)microsec_clock()
in gettod.c
)] is very inaccurate. It regularly jumps back and forth by a whole second, presumably in an attempt to keep up with libc time()
. This large jitter is what "accidentally" caused the daemon timer to be triggered.
Given a simple test program:
#include <stdio.h>
#include <tcp.h>
int main()
{
const DWORD end = set_timeout(10000);
DWORD now;
do
{
now = set_timeout(0);
printf("%lu\n", now);
}
while (now < end);
return 0;
}
Compare to 8254 timer ( [BIOS timer (timer.c
, millisec_clock()
/clockbits()
)set_timeout()
in timer.c
)] that is used in 16-bit builds:
This has lower resolution, but at least is more monotonic. Maybe the rdtsc code should be disabled for now until a better algorithm is found.
This is a list of little things I reported through the Watt-32 mailing list in February 2019. I fetched now the latest Watt-32 master version from the github repo and I can confirm that all these issues are still present.
It is about building Watt-32 using the watcom compiler under real mode DOS.
The reason is that directory "build/watcom" does not exist. The solution is simple: mkdir build/watcom
As a quick hack I simply removed the cflags.h target from the makefile and created it by hand... That's not a solution of course. Not sure what the solution could be here - the problem lies, I think, in the maximum number of arguments that the shell is able to pass to a command (echo, in this case).
"cflags_buf.h not found"
In fact, the makefile was creating the cflags_buf.h all right, but then
wmake was unable to find it. It seems to be a 8+3 problem. I renamed cflags_buf.h to cflagsbf.h (and replaced all references to it in all source files), and the problem went away. Since the rest of the Watt-32 source base is 8+3 compatible, perhaps could the cflags_buf.h thing be simplified to 8+3 as well?
This one I am truly clueless about. I mean, I do confirm that __syserr00
was missing in the syserr.c file, but why it is missing is a mystery to
me, since this is some kind of auto-generated file. Curiously, I did not
run into this problem when compiling under the windows platform. The
hack I applied is very simple, I naively added this to syserr.c:
char __syserr00[] = "";
....and then, at last, Watt-32 compiled.
There's some asm code in sys/swap.h
in AT&T syntax. This breaks any code compiled with gcc -masm=intel
that includes this header.
Could the __builtin_bswap
functions be used instead?
Hi!
I was just looking into using the C++ asio library with djgpp/watt32, but it seems we're missing a few things.
#define WATT32_NO_OLDIES
#define ASIO_DISABLE_THREADS
#include <asio.hpp>
Compiling the above test file, I see:
Missing functions:
readv
/writev
: These already exist as readv_s
and writev_s
. Can we get these declared in <sys/uio.h>
?socketpair
: Can be ifdef'd out, as is done for Windows.Missing errno:
ECANCELED
: I suppose I could just define it to some random number.Missing signal options:
SA_RESTART
:SA_NOCLDWAIT
: Should be provided by libc, but I think I can safely define these to 0.Missing ipv6 stuff:
IPPROTO_IPV6
IPV6_JOIN_GROUP
IPV6_LEAVE_GROUP
IPV6_MULTICAST_IF
IPV6_MULTICAST_LOOP
IPV6_MULTICAST_HOPS
IPV6_UNICAST_HOPS
Seems asio expects a complete ipv6 implementation, I don't see an obvious way to disable it. What's the status on that?
On Wireshark I see Watt-32 transmits many duplicate ACKs. About every 25ms, it sends out 30-100 of these in a row. In transferring 10MB of data, these account for about 45% of all packets sent.
From googling I gather that this may be used to request a retransmit. However it begins sending these within nanoseconds after the last data packet, and even when the remote then sends an ACK, it continues to send more of these for a while.
Transfer speed is not great, ~1600 KB/s. I suspect all these empty packets are hurting performance.
Hi,
RE: DOSBox-X
Building 'watt32s' DJGPP library trapped the follow error:
v v v
jgpp-receive.o -c receive.c
receive.c: In function ‘receive’
receive.c:95:29: error: invalid application of 'sizeof’ to incomplete type ‘struct sockaddr_ll'
95 | ____________________sizeof(struct sockaddr_ll)
| ___________________________^~~~~~
make: xxx [djgpp.mak:172: build/djgpp/receive.o] Error 1
^ ^ ^
Can it be patched and which djgpp platform was source code built on?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.