Revision 0bab00f3 vl.c

b/vl.c
2130 2130
}
2131 2131
#endif
2132 2132

  
2133
/***********************************************************/
2134
/* UDP Net console */
2135

  
2136
typedef struct {
2137
    IOCanRWHandler *fd_can_read;
2138
    IOReadHandler *fd_read;
2139
    void *fd_opaque;
2140
    int fd;
2141
    struct sockaddr_in daddr;
2142
    char buf[1024];
2143
    int bufcnt;
2144
    int bufptr;
2145
    int max_size;
2146
} NetCharDriver;
2147

  
2148
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2149
{
2150
    NetCharDriver *s = chr->opaque;
2151

  
2152
    return sendto(s->fd, buf, len, 0,
2153
                  (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
2154
}
2155

  
2156
static int udp_chr_read_poll(void *opaque)
2157
{
2158
    CharDriverState *chr = opaque;
2159
    NetCharDriver *s = chr->opaque;
2160

  
2161
    s->max_size = s->fd_can_read(s->fd_opaque);
2162

  
2163
    /* If there were any stray characters in the queue process them
2164
     * first
2165
     */
2166
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2167
        s->fd_read(s->fd_opaque, &s->buf[s->bufptr], 1);
2168
        s->bufptr++;
2169
        s->max_size = s->fd_can_read(s->fd_opaque);
2170
    }
2171
    return s->max_size;
2172
}
2173

  
2174
static void udp_chr_read(void *opaque)
2175
{
2176
    CharDriverState *chr = opaque;
2177
    NetCharDriver *s = chr->opaque;
2178

  
2179
    if (s->max_size == 0)
2180
        return;
2181
    s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
2182
    s->bufptr = s->bufcnt;
2183
    if (s->bufcnt <= 0)
2184
        return;
2185

  
2186
    s->bufptr = 0;
2187
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2188
        s->fd_read(s->fd_opaque, &s->buf[s->bufptr], 1);
2189
        s->bufptr++;
2190
        s->max_size = s->fd_can_read(s->fd_opaque);
2191
    }
2192
}
2193

  
2194
static void udp_chr_add_read_handler(CharDriverState *chr,
2195
                                    IOCanRWHandler *fd_can_read,
2196
                                    IOReadHandler *fd_read, void *opaque)
2197
{
2198
    NetCharDriver *s = chr->opaque;
2199

  
2200
    if (s->fd >= 0) {
2201
        s->fd_can_read = fd_can_read;
2202
        s->fd_read = fd_read;
2203
        s->fd_opaque = opaque;
2204
        qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
2205
                             udp_chr_read, NULL, chr);
2206
    }
2207
}
2208

  
2209
int parse_host_port(struct sockaddr_in *saddr, const char *str);
2210

  
2211
CharDriverState *qemu_chr_open_udp(const char *def)
2212
{
2213
    CharDriverState *chr = NULL;
2214
    NetCharDriver *s = NULL;
2215
    int fd = -1;
2216
    int con_type;
2217
    struct sockaddr_in addr;
2218
    const char *p, *r;
2219
    int port;
2220

  
2221
    chr = qemu_mallocz(sizeof(CharDriverState));
2222
    if (!chr)
2223
        goto return_err;
2224
    s = qemu_mallocz(sizeof(NetCharDriver));
2225
    if (!s)
2226
        goto return_err;
2227

  
2228
    fd = socket(PF_INET, SOCK_DGRAM, 0);
2229
    if (fd < 0) {
2230
        perror("socket(PF_INET, SOCK_DGRAM)");
2231
        goto return_err;
2232
    }
2233

  
2234
    /* There are three types of port definitions
2235
     * 1) udp:remote_port
2236
     *    Juse use 0.0.0.0 for the IP and send to remote
2237
     * 2) udp:remote_host:port
2238
     *    Use a IP and send traffic to remote
2239
     * 3) udp:local_port:remote_host:remote_port
2240
     *    Use local_port as the originator + #2
2241
     */
2242
    con_type = 0;
2243
    p = def;
2244
    while ((p = strchr(p, ':'))) {
2245
        p++;
2246
        con_type++;
2247
    }
2248

  
2249
    p = def;
2250
    memset(&addr,0,sizeof(addr));
2251
    addr.sin_family = AF_INET;
2252
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
2253
    s->daddr.sin_family = AF_INET;
2254
    s->daddr.sin_addr.s_addr = htonl(INADDR_ANY);
2255

  
2256
    switch (con_type) {
2257
        case 0:
2258
            port = strtol(p, (char **)&r, 0);
2259
            if (r == p) {
2260
                fprintf(stderr, "Error parsing port number\n");
2261
                goto return_err;
2262
            }
2263
            s->daddr.sin_port = htons((short)port);
2264
            break;
2265
        case 2:
2266
            port = strtol(p, (char **)&r, 0);
2267
            if (r == p) {
2268
                fprintf(stderr, "Error parsing port number\n");
2269
                goto return_err;
2270
            }
2271
            addr.sin_port = htons((short)port);
2272
            p = r + 1;
2273
            /* Fall through to case 1 now that we have the local port */
2274
        case 1:
2275
            if (parse_host_port(&s->daddr, p) < 0) {
2276
                fprintf(stderr, "Error parsing host name and port\n");
2277
                goto return_err;
2278
            }
2279
            break;
2280
        default:
2281
            fprintf(stderr, "Too many ':' characters\n");
2282
            goto return_err;
2283
    }
2284

  
2285
    if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
2286
    {
2287
        perror("bind");
2288
        goto return_err;
2289
    }
2290

  
2291
    s->fd = fd;
2292
    s->bufcnt = 0;
2293
    s->bufptr = 0;
2294
    chr->opaque = s;
2295
    chr->chr_write = udp_chr_write;
2296
    chr->chr_add_read_handler = udp_chr_add_read_handler;
2297
    return chr;
2298

  
2299
return_err:
2300
    if (chr)
2301
        free(chr);
2302
    if (s)
2303
        free(s);
2304
    if (fd >= 0)
2305
        closesocket(fd);
2306
    return NULL;
2307
}
2308

  
2309
/***********************************************************/
2310
/* TCP Net console */
2311

  
2312
typedef struct {
2313
    IOCanRWHandler *fd_can_read;
2314
    IOReadHandler *fd_read;
2315
    void *fd_opaque;
2316
    int fd, listen_fd;
2317
    int connected;
2318
    int max_size;
2319
} TCPCharDriver;
2320

  
2321
static void tcp_chr_accept(void *opaque);
2322

  
2323
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2324
{
2325
    TCPCharDriver *s = chr->opaque;
2326
    if (s->connected) {
2327
        return send_all(s->fd, buf, len);
2328
    } else {
2329
        /* XXX: indicate an error ? */
2330
        return len;
2331
    }
2332
}
2333

  
2334
static int tcp_chr_read_poll(void *opaque)
2335
{
2336
    CharDriverState *chr = opaque;
2337
    TCPCharDriver *s = chr->opaque;
2338
    if (!s->connected)
2339
        return 0;
2340
    s->max_size = s->fd_can_read(s->fd_opaque);
2341
    return s->max_size;
2342
}
2343

  
2344
static void tcp_chr_read(void *opaque)
2345
{
2346
    CharDriverState *chr = opaque;
2347
    TCPCharDriver *s = chr->opaque;
2348
    uint8_t buf[1024];
2349
    int len, size;
2350

  
2351
    if (!s->connected || s->max_size <= 0)
2352
        return;
2353
    len = sizeof(buf);
2354
    if (len > s->max_size)
2355
        len = s->max_size;
2356
    size = recv(s->fd, buf, len, 0);
2357
    if (size == 0) {
2358
        /* connection closed */
2359
        s->connected = 0;
2360
        if (s->listen_fd >= 0) {
2361
            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2362
        }
2363
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
2364
        closesocket(s->fd);
2365
        s->fd = -1;
2366
    } else if (size > 0) {
2367
        s->fd_read(s->fd_opaque, buf, size);
2368
    }
2369
}
2370

  
2371
static void tcp_chr_add_read_handler(CharDriverState *chr,
2372
                                     IOCanRWHandler *fd_can_read,
2373
                                    IOReadHandler *fd_read, void *opaque)
2374
{
2375
    TCPCharDriver *s = chr->opaque;
2376

  
2377
    s->fd_can_read = fd_can_read;
2378
    s->fd_read = fd_read;
2379
    s->fd_opaque = opaque;
2380
}
2381

  
2382
static void tcp_chr_connect(void *opaque)
2383
{
2384
    CharDriverState *chr = opaque;
2385
    TCPCharDriver *s = chr->opaque;
2386

  
2387
    s->connected = 1;
2388
    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
2389
                         tcp_chr_read, NULL, chr);
2390
}
2391

  
2392
static void tcp_chr_accept(void *opaque)
2393
{
2394
    CharDriverState *chr = opaque;
2395
    TCPCharDriver *s = chr->opaque;
2396
    struct sockaddr_in saddr;
2397
    socklen_t len;
2398
    int fd;
2399

  
2400
    for(;;) {
2401
        len = sizeof(saddr);
2402
        fd = accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
2403
        if (fd < 0 && errno != EINTR) {
2404
            return;
2405
        } else if (fd >= 0) {
2406
            break;
2407
        }
2408
    }
2409
    socket_set_nonblock(fd);
2410
    s->fd = fd;
2411
    qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
2412
    tcp_chr_connect(chr);
2413
}
2414

  
2415
static void tcp_chr_close(CharDriverState *chr)
2416
{
2417
    TCPCharDriver *s = chr->opaque;
2418
    if (s->fd >= 0)
2419
        closesocket(s->fd);
2420
    if (s->listen_fd >= 0)
2421
        closesocket(s->listen_fd);
2422
    qemu_free(s);
2423
}
2424

  
2425
static CharDriverState *qemu_chr_open_tcp(const char *host_str, 
2426
                                          int is_listen)
2427
{
2428
    CharDriverState *chr = NULL;
2429
    TCPCharDriver *s = NULL;
2430
    int fd = -1, ret, err, val;
2431
    struct sockaddr_in saddr;
2432

  
2433
    if (parse_host_port(&saddr, host_str) < 0)
2434
        goto fail;
2435

  
2436
    chr = qemu_mallocz(sizeof(CharDriverState));
2437
    if (!chr)
2438
        goto fail;
2439
    s = qemu_mallocz(sizeof(TCPCharDriver));
2440
    if (!s)
2441
        goto fail;
2442
    
2443
    fd = socket(PF_INET, SOCK_STREAM, 0);
2444
    if (fd < 0) 
2445
        goto fail;
2446
    socket_set_nonblock(fd);
2447

  
2448
    s->connected = 0;
2449
    s->fd = -1;
2450
    s->listen_fd = -1;
2451
    if (is_listen) {
2452
        /* allow fast reuse */
2453
        val = 1;
2454
        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
2455
        
2456
        ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2457
        if (ret < 0) 
2458
            goto fail;
2459
        ret = listen(fd, 0);
2460
        if (ret < 0)
2461
            goto fail;
2462
        s->listen_fd = fd;
2463
        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2464
    } else {
2465
        for(;;) {
2466
            ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2467
            if (ret < 0) {
2468
                err = socket_error();
2469
                if (err == EINTR || err == EWOULDBLOCK) {
2470
                } else if (err == EINPROGRESS) {
2471
                    break;
2472
                } else {
2473
                    goto fail;
2474
                }
2475
            } else {
2476
                s->connected = 1;
2477
                break;
2478
            }
2479
        }
2480
        s->fd = fd;
2481
        if (s->connected)
2482
            tcp_chr_connect(chr);
2483
        else
2484
            qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
2485
    }
2486
    
2487
    chr->opaque = s;
2488
    chr->chr_write = tcp_chr_write;
2489
    chr->chr_add_read_handler = tcp_chr_add_read_handler;
2490
    chr->chr_close = tcp_chr_close;
2491
    return chr;
2492
 fail:
2493
    if (fd >= 0)
2494
        closesocket(fd);
2495
    qemu_free(s);
2496
    qemu_free(chr);
2497
    return NULL;
2498
}
2499

  
2133 2500
CharDriverState *qemu_chr_open(const char *filename)
2134 2501
{
2135 2502
    const char *p;
......
2139 2506
    } else if (!strcmp(filename, "null")) {
2140 2507
        return qemu_chr_open_null();
2141 2508
    } else 
2509
    if (strstart(filename, "tcp:", &p)) {
2510
        return qemu_chr_open_tcp(p, 0);
2511
    } else
2512
    if (strstart(filename, "tcpl:", &p)) {
2513
        return qemu_chr_open_tcp(p, 1);
2514
    } else
2515
    if (strstart(filename, "udp:", &p)) {
2516
        return qemu_chr_open_udp(p);
2517
    } else
2142 2518
#ifndef _WIN32
2143 2519
    if (strstart(filename, "file:", &p)) {
2144 2520
        return qemu_chr_open_file_out(p);
......
2844 3220
    socket_set_nonblock(fd);
2845 3221
    return fd;
2846 3222
fail:
2847
    if (fd>=0) close(fd);
3223
    if (fd >= 0) 
3224
        closesocket(fd);
2848 3225
    return -1;
2849 3226
}
2850 3227

  
......
2972 3349
    }
2973 3350
    s1 = net_socket_fd_init(s->vlan, fd, 1); 
2974 3351
    if (!s1) {
2975
        close(fd);
3352
        closesocket(fd);
2976 3353
    } else {
2977 3354
        snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
2978 3355
                 "socket: connection from %s:%d", 

Also available in: Unified diff