207 |
mateuszvis |
1 |
/*
|
|
|
2 |
* This file is part of the pkgnet package - the SvarDOS package manager.
|
1502 |
mateusz.vi |
3 |
* Copyright (C) Mateusz Viste 2013-2023
|
207 |
mateuszvis |
4 |
*
|
|
|
5 |
* Provides all network functions used by pkgnet, wrapped around the
|
|
|
6 |
* Watt-32 TCP/IP stack.
|
|
|
7 |
*/
|
|
|
8 |
|
|
|
9 |
#include <stdlib.h>
|
|
|
10 |
|
|
|
11 |
/* Watt32 */
|
|
|
12 |
#include <tcp.h>
|
|
|
13 |
|
|
|
14 |
#include "net.h" /* include self for control */
|
|
|
15 |
|
|
|
16 |
|
335 |
mateuszvis |
17 |
/* if there is enough memory, net_connect() will try setting up a tcp window
|
|
|
18 |
* larger than the WATT32's default of only 2K
|
|
|
19 |
* on my system's DOSEMU install the relation between tcp buffer and download
|
|
|
20 |
* speed were measured as follows (this is on a 4 Mbps ADSL link):
|
|
|
21 |
* 2K = 20 KiB/s
|
|
|
22 |
* 4K = 51 KiB/s
|
|
|
23 |
* 8K = 67 KiB/s
|
|
|
24 |
* 9K = 98 KiB/s
|
|
|
25 |
* 10K = 98 KiB/s
|
|
|
26 |
* 16K = 96 KiB/s
|
|
|
27 |
* 32K = 98 KiB/s
|
|
|
28 |
* 60K = 98 KiB/s
|
|
|
29 |
*/
|
|
|
30 |
|
333 |
mateuszvis |
31 |
struct net_tcpsocket {
|
1133 |
mateusz.vi |
32 |
tcp_Socket sock; /* watt32 socket */
|
335 |
mateuszvis |
33 |
char tcpbuff[1];
|
333 |
mateuszvis |
34 |
};
|
|
|
35 |
|
|
|
36 |
|
1560 |
mateusz.vi |
37 |
int net_dnsresolve(char *ip, const char *name, int retries) {
|
|
|
38 |
unsigned long ipnum;
|
|
|
39 |
do {
|
|
|
40 |
ipnum = resolve(name); /* I could use WatTCP's lookup_host() to do all the
|
|
|
41 |
job for me, unfortunately lookup_host() issues
|
|
|
42 |
wild outs() calls putting garbage on screen... */
|
|
|
43 |
} while ((ipnum == 0) && (retries-- > 0));
|
|
|
44 |
if (ipnum == 0) return(-1);
|
|
|
45 |
_inet_ntoa(ip, ipnum); /* convert to string */
|
|
|
46 |
return(0);
|
|
|
47 |
}
|
|
|
48 |
|
|
|
49 |
|
207 |
mateuszvis |
50 |
static int dummy_printf(const char * format, ...) {
|
|
|
51 |
if (format == NULL) return(-1);
|
|
|
52 |
return(0);
|
|
|
53 |
}
|
|
|
54 |
|
|
|
55 |
|
|
|
56 |
/* must be called before using libtcp. returns 0 on success, or non-zero if network subsystem is not available. */
|
|
|
57 |
int net_init(void) {
|
|
|
58 |
tzset();
|
|
|
59 |
_printf = dummy_printf; /* this is to avoid watt32 printing its stuff to console */
|
|
|
60 |
return(sock_init());
|
|
|
61 |
}
|
|
|
62 |
|
|
|
63 |
|
1132 |
mateusz.vi |
64 |
struct net_tcpsocket *net_connect(const char *ipstr, unsigned short port, unsigned short buffsz) {
|
|
|
65 |
struct net_tcpsocket *resultsock;
|
207 |
mateuszvis |
66 |
unsigned long ipaddr;
|
|
|
67 |
|
|
|
68 |
/* convert ip to value */
|
|
|
69 |
ipaddr = _inet_addr(ipstr);
|
|
|
70 |
if (ipaddr == 0) return(NULL);
|
|
|
71 |
|
1132 |
mateusz.vi |
72 |
/* ignore buffsz smaller than 2K (wattcp already has a 2K buffer) */
|
|
|
73 |
if (buffsz <= 2048) buffsz = 0;
|
|
|
74 |
|
|
|
75 |
resultsock = calloc(sizeof(struct net_tcpsocket) + buffsz, 1);
|
207 |
mateuszvis |
76 |
if (resultsock == NULL) return(NULL);
|
|
|
77 |
|
1133 |
mateusz.vi |
78 |
if (!tcp_open(&(resultsock->sock), 0, ipaddr, port, NULL)) {
|
|
|
79 |
sock_abort(&(resultsock->sock));
|
207 |
mateuszvis |
80 |
free(resultsock);
|
|
|
81 |
return(NULL);
|
|
|
82 |
}
|
|
|
83 |
|
1132 |
mateusz.vi |
84 |
/* set user-managed buffer if requested (watt32's default is only 2K)
|
335 |
mateuszvis |
85 |
* this must be set AFTER tcp_open(), since the latter rewrites the tcp
|
|
|
86 |
* rx buffer */
|
1133 |
mateusz.vi |
87 |
if (buffsz > 0) sock_setbuf(&(resultsock->sock), resultsock->tcpbuff, buffsz);
|
335 |
mateuszvis |
88 |
|
207 |
mateuszvis |
89 |
return(resultsock);
|
|
|
90 |
}
|
|
|
91 |
|
|
|
92 |
|
329 |
mateuszvis |
93 |
int net_isconnected(struct net_tcpsocket *s) {
|
1133 |
mateusz.vi |
94 |
if (tcp_tick(&(s->sock)) == 0) return(-1);
|
|
|
95 |
if (sock_established(&(s->sock)) == 0) return(0);
|
207 |
mateuszvis |
96 |
return(1);
|
|
|
97 |
}
|
|
|
98 |
|
|
|
99 |
|
|
|
100 |
/* Sends data on socket 'socket'.
|
|
|
101 |
Returns the number of bytes sent on success, and < 0 otherwise */
|
329 |
mateuszvis |
102 |
int net_send(struct net_tcpsocket *socket, const void *line, long len) {
|
207 |
mateuszvis |
103 |
/* call this to let Watt-32 handle its internal stuff */
|
1133 |
mateusz.vi |
104 |
if (tcp_tick(&(socket->sock)) == 0) return(-1);
|
207 |
mateuszvis |
105 |
/* send bytes */
|
1133 |
mateusz.vi |
106 |
return(sock_write(&(socket->sock), line, len));
|
207 |
mateuszvis |
107 |
}
|
|
|
108 |
|
|
|
109 |
|
|
|
110 |
/* Reads data from socket 'sock' and write it into buffer 'buff', until end of connection. Will fall into error if the amount of data is bigger than 'maxlen' bytes.
|
|
|
111 |
Returns the amount of data read (in bytes) on success, or a negative value otherwise. The error code can be translated into a human error message via libtcp_strerr(). */
|
329 |
mateuszvis |
112 |
int net_recv(struct net_tcpsocket *socket, void *buff, long maxlen) {
|
207 |
mateuszvis |
113 |
/* call this to let WatTCP handle its internal stuff */
|
1133 |
mateusz.vi |
114 |
if (tcp_tick(&(socket->sock)) == 0) return(-1);
|
|
|
115 |
return(sock_fastread(&(socket->sock), buff, maxlen));
|
207 |
mateuszvis |
116 |
}
|
|
|
117 |
|
|
|
118 |
|
|
|
119 |
/* Close the 'sock' socket. */
|
|
|
120 |
void net_close(struct net_tcpsocket *socket) {
|
|
|
121 |
/* I could use sock_close() and sock_wait_closed() if I'd want to be
|
|
|
122 |
* friendly, but it's much easier on the tcp stack to send a single RST and
|
|
|
123 |
* forget about the connection (esp. if the peer is misbehaving) */
|
1133 |
mateusz.vi |
124 |
sock_abort(&(socket->sock));
|
207 |
mateuszvis |
125 |
free(socket);
|
|
|
126 |
}
|
|
|
127 |
|
|
|
128 |
|
1502 |
mateusz.vi |
129 |
void net_shut(void) {
|
|
|
130 |
sock_exit();
|
|
|
131 |
}
|
|
|
132 |
|
|
|
133 |
|
207 |
mateuszvis |
134 |
const char *net_engine(void) {
|
|
|
135 |
return(wattcpVersion());
|
|
|
136 |
}
|