Coverage Report

Created: 2026-08-08 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/protocols/radius/tcp.c
Line
Count
Source
1
/*
2
 *  This program is free software; you can redistribute it and/or modify
3
 *  it under the terms of the GNU General Public License as published by
4
 *  the Free Software Foundation; either version 2 of the License, or
5
 *  (at your option) any later version.
6
 *
7
 *  This program is distributed in the hope that it will be useful,
8
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 *  GNU General Public License for more details.
11
 *
12
 *  You should have received a copy of the GNU General Public License
13
 *  along with this program; if not, write to the Free Software
14
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15
 */
16
17
/**
18
 * $Id: 76cf928bebfbd1ed16ca2dd648c4df95228b7573 $
19
 *
20
 * @file protocols/radius/packet.c
21
 * @brief TCP-specific functions.
22
 *
23
 * @copyright (C) 2009 Dante http://dante.net
24
 */
25
RCSID("$Id: 76cf928bebfbd1ed16ca2dd648c4df95228b7573 $")
26
27
#include <freeradius-devel/radius/radius.h>
28
#include <freeradius-devel/util/syserror.h>
29
#include "tcp.h"
30
31
/*
32
 *  This ASSUMES that the socket is marked as O_NONBLOCK, which
33
 *  the function above does set, if your system supports it.
34
 */
35
ssize_t fr_tcp_read_packet(int sockfd, uint8_t *buffer, size_t size, size_t *total, uint32_t max_attributes, bool require_message_authenticator)
36
0
{
37
0
  ssize_t slen;
38
0
  size_t packet_len, hdr_len;
39
0
  uint8_t *start, *end;
40
41
0
  fr_assert(*total < size);
42
0
  start = buffer + *total;
43
0
  end = buffer + size;
44
45
0
  slen = recv(sockfd, start, (size_t) (end - start), 0);
46
0
  if (slen <= 0) return -1; /* 0 means EOF for non-blocking TCP reads */
47
48
0
  packet_len = *total + slen;
49
50
  /*
51
   *  Not enough for a header, we don't have a packet.
52
   */
53
0
  if (packet_len < 4) {
54
0
    *total = packet_len;
55
0
    return 0;
56
0
  }
57
58
0
  hdr_len = fr_nbo_to_uint16(buffer + 2);
59
0
  if ((hdr_len < RADIUS_HEADER_LENGTH) || (hdr_len >  RADIUS_MAX_PACKET_SIZE)) return -1;
60
61
0
  if (packet_len < hdr_len) {
62
0
    *total = packet_len;
63
0
    return 0;
64
0
  }
65
66
  /*
67
   *  See if it's a well-formed RADIUS packet.
68
   */
69
0
  if (!fr_radius_ok(buffer, &hdr_len, max_attributes, require_message_authenticator, NULL)) {
70
0
    return -1;
71
0
  }
72
73
0
  *total = hdr_len;
74
0
  return hdr_len;
75
0
}