Subversion Repositories SvarDOS

Rev

Rev 335 | Rev 885 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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