Subversion Repositories SvarDOS

Rev

Rev 885 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
207 mateuszvis 1
/*
2
 * This file is part of the pkgnet package - the SvarDOS package manager.
3
 * Copyright (C) Mateusz Viste 2013-2021
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
#define TCPBUFF_SIZE (16 * 1024)
31
 
32
 
333 mateuszvis 33
struct net_tcpsocket {
34
  tcp_Socket *sock;
35
  tcp_Socket _sock; /* watt32 socket */
335 mateuszvis 36
  char tcpbuff[1];
333 mateuszvis 37
};
38
 
39
 
885 mateusz.vi 40
int net_dnsresolve(char *ip, const char *name, int retries) {
207 mateuszvis 41
  unsigned long ipnum;
885 mateusz.vi 42
  do {
43
    ipnum = resolve(name); /* I could use WatTCP's lookup_host() to do all the
44
                              job for me, unfortunately lookup_host() issues
45
                              wild outs() calls putting garbage on screen... */
46
  } while ((ipnum == 0) && (retries-- > 0));
207 mateuszvis 47
  if (ipnum == 0) return(-1);
48
  _inet_ntoa(ip, ipnum); /* convert to string */
49
  return(0);
50
}
51
 
52
 
53
static int dummy_printf(const char * format, ...) {
54
  if (format == NULL) return(-1);
55
  return(0);
56
}
57
 
58
 
59
/* must be called before using libtcp. returns 0 on success, or non-zero if network subsystem is not available. */
60
int net_init(void) {
61
  tzset();
62
  _printf = dummy_printf;  /* this is to avoid watt32 printing its stuff to console */
63
  return(sock_init());
64
}
65
 
66
 
67
struct net_tcpsocket *net_connect(const char *ipstr, unsigned short port) {
335 mateuszvis 68
  struct net_tcpsocket *resultsock, *resizsock;
207 mateuszvis 69
  unsigned long ipaddr;
70
 
71
  /* convert ip to value */
72
  ipaddr = _inet_addr(ipstr);
73
  if (ipaddr == 0) return(NULL);
74
 
333 mateuszvis 75
  resultsock = calloc(sizeof(struct net_tcpsocket), 1);
207 mateuszvis 76
  if (resultsock == NULL) return(NULL);
333 mateuszvis 77
  resultsock->sock = &(resultsock->_sock);
207 mateuszvis 78
 
79
  if (!tcp_open(resultsock->sock, 0, ipaddr, port, NULL)) {
80
    sock_abort(resultsock->sock);
81
    free(resultsock);
82
    return(NULL);
83
  }
84
 
335 mateuszvis 85
  /* set user-managed buffer if possible (watt32's default is only 2K)
86
   * this must be set AFTER tcp_open(), since the latter rewrites the tcp
87
   * rx buffer */
88
  resizsock = realloc(resultsock, sizeof(struct net_tcpsocket) + TCPBUFF_SIZE);
89
  if (resizsock != NULL) {
90
    resultsock = resizsock;
91
    sock_setbuf(resultsock->sock, resultsock->tcpbuff, TCPBUFF_SIZE);
92
  }
93
 
207 mateuszvis 94
  return(resultsock);
95
}
96
 
97
 
329 mateuszvis 98
int net_isconnected(struct net_tcpsocket *s) {
207 mateuszvis 99
  if (tcp_tick(s->sock) == 0) return(-1);
100
  if (sock_established(s->sock) == 0) return(0);
101
  return(1);
102
}
103
 
104
 
105
/* Sends data on socket 'socket'.
106
   Returns the number of bytes sent on success, and < 0 otherwise */
329 mateuszvis 107
int net_send(struct net_tcpsocket *socket, const void *line, long len) {
207 mateuszvis 108
  /* call this to let Watt-32 handle its internal stuff */
109
  if (tcp_tick(socket->sock) == 0) return(-1);
110
  /* send bytes */
329 mateuszvis 111
  return(sock_write(socket->sock, line, len));
207 mateuszvis 112
}
113
 
114
 
115
/* 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.
116
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 117
int net_recv(struct net_tcpsocket *socket, void *buff, long maxlen) {
207 mateuszvis 118
  /* call this to let WatTCP handle its internal stuff */
119
  if (tcp_tick(socket->sock) == 0) return(-1);
329 mateuszvis 120
  return(sock_fastread(socket->sock, buff, maxlen));
207 mateuszvis 121
}
122
 
123
 
124
/* Close the 'sock' socket. */
125
void net_close(struct net_tcpsocket *socket) {
126
  /* I could use sock_close() and sock_wait_closed() if I'd want to be
127
   * friendly, but it's much easier on the tcp stack to send a single RST and
128
   * forget about the connection (esp. if the peer is misbehaving) */
129
  sock_abort(socket->sock);
130
  free(socket);
131
}
132
 
133
 
134
const char *net_engine(void) {
135
  return(wattcpVersion());
136
}