Subversion Repositories SvarDOS

Rev

Rev 1132 | Rev 1502 | Go to most recent revision | 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.
1133 mateusz.vi 3
 * Copyright (C) Mateusz Viste 2013-2022
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
 
885 mateusz.vi 37
int net_dnsresolve(char *ip, const char *name, int retries) {
207 mateuszvis 38
  unsigned long ipnum;
885 mateusz.vi 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));
207 mateuszvis 44
  if (ipnum == 0) return(-1);
45
  _inet_ntoa(ip, ipnum); /* convert to string */
46
  return(0);
47
}
48
 
49
 
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
 
129
const char *net_engine(void) {
130
  return(wattcpVersion());
131
}