The Ephemeral Port Range

The Ephemeral Port Range

A TCP/IPv4 connection consists of two endpoints, and each endpoint consistsof an IP address and a port number.  Therefore, when a client user connectsto a server computer, an established connection can be thought of as the 4-tupleof (server IP, server port, client IP, client port).  Usually three of thefour are readily known -- client machine uses its own IP address and whenconnecting to a remote service, the server machine's IP address and service portnumber are required.  

What is not immediately evident is that when a connection is established thatthe client side of the connection uses a port number.  Unless a clientprogram explicitly requests a specific port number, the port number used is an ephemeralport number.  Ephemeral ports are temporary ports assigned by a machine'sIP stack, and are assigned from a designated range of ports for thispurpose.  When the connection terminates, the ephemeral port is availablefor reuse, although most IP stacks won't reuse that port number until the entirepool of ephemeral ports have been used.  So, if the client programreconnects, it will be assigned a different ephemeral port number for its sideof the new connection.

Similarly, for UDP/IP, when a datagram is sent by a client from an unboundport number, an ephemeral port number is assigned automatically so the receivingend can reply to the sender.

Contents

Limits Implied by the Ephemeral Port Range

Another important ramification of the ephemeral port range is that it limitsthe maximum number of connections from one machine to a specific service on aremote machine!  The TCP/IP protocol uses the connection's 4-tuple todistinguish between connections, so if the ephemeral port range is only 4000ports wide, that means that there can only be 4000 unique connections from aclient machine to a remote service at one time.

A port range of 4000 may seem large, but it is actually small for 21stcentury computing demands when you consider that a TCP connection must expirethrough the TIME_WAIT state before it is really completed.  For example,even if both sides of a connection properly close their ends of the connection,due to TCP's error control, each side must wait until the TIME_WAIT state isexpired before the connection's resources can really be disposed.  TheTIME_WAIT state is twice the MSL (maximum segment lifetime) which, depending onthe IP stack, is usually configured to be 240 seconds total.  That meansthat you could have only 4000 connections per 240 second window, and in practicethis can be exhausted.

Problems Exacerbated by the File Transfer Protocol

For example, the File Transfer Protocol (FTP) uses a separate data connectionfor each data transfer, so this phenomenon can be experienced when FTP'inghundreds of small files over a fast local network.  When all ephemeralports are in use, a compatible BSD Sockets TCP/IP stack will return"Address already in use" errors.

The second problem with the FTP is that with the default mode of operation,the separate data transfer connections originate from the server machine back tothe client machine to an ephemeral port number requested by the clientprogram.  Since many firewalls restrict incoming connections, when the FTPdata connection tries to connect to an ephemeral port number on the clientmachine, the connection may be denied by the firewall since the port numberisn't a well-known service port.

It may be best to illustrate this by showing a sample FTP session:

Client:USER anonymous 
Server:331 Guest login ok, send your e-mail address as password. 
Client:PASS NcFTP@ 
Server:230 Logged in anonymously. 
Client:PORT 192,168,1,2,7,138The client wants the server to send to port number 1930 on IP address 192.168.1.2.
Server:200 PORT command successful. 
Client:LIST 
Server:150 Opening ASCII mode data connection for /bin/ls.The server now connects out from port 20 to port 1930 on 192.168.1.2.
Server:226 Listing completed.That succeeded, so the data is now sent over the established data connection.
Client:QUIT 
Server:221 Goodbye. 

Now, had there been a restrictive firewall on the client machine, when theconnection from the server to port 1930 on the client would have failed. Note that the client program did not explicitly ask for port 1930 -- it justasked for an unused port number to use for this temporary data connection.

Traditional Configuration of the Ephemeral Port Range

The BSD Sockets TCP/IP stack used ports 1024 through 4999 as ephemeralports.  Additionally, ports 1 through 1023 were intended for systemsservices running as the superuser, so those ports are called reservedports.  

As discussed earlier, BSD's choice of the ephemeral port range is unfortunatebecause of its relatively small size (3975 ports) and its low numberedposition.  We feel that the default range should be 49152 through 65535,which is both much larger (16383 ports) and is at the very top of the full portrange.

Firewalling the Ephemeral Port Range

For firewalls, often administrators choose to restrict access to as many portnumbers as possible.  For cases where inbound connections to the ephemeralports is required, an entire range of ports must be opened.  It isimperative that when opening a range of ports on the firewall that no systemservices are listening on ports in the open range.  Administrators willoften want to open a specific range on the firewall, and then for each machineon the internal network, make sure that the ephemeral port range on the machinecoincides with the open range on the firewall.

It must be made clear that the ephemeral port range on machines on theinternal network often do not coincide with each other since different operatingsystems may use different ranges.  That is why it can be time consuming tomanually configure each machine's ephemeral port range so it coincides with theopen range on the firewall.  As a result, administrators often end upchanging to a policy of allowing all incoming ports and deny access to specificports when needed.

Luckily, it may not be necessary to open the ephemeral port range.  Itis usually only necessary when FTP is being served to the outside world (Passive"PASV" data connections use inbound ephemeral ports), or when FTPclient access must work in non-passive mode ("PORT" connections fromthe server are inbound to clients using ephemeral ports).

Changing the Ephemeral Port Range

It is desirable to change which port numbers are used for the ephemeral portrange for any of the following:

To use a larger range so that more simultaneous connections are possible

To shift the range to the higher numbered ports.  The higher numberedports should be used as ephemeral ports because they are less likely to be usedas port numbers for system services.  Well-known service ports havetraditionally been assigned to lower port numbers.

To change the range to coincide with other systems for purposes offirewalling and automatic network address translation. 

When changing the range, we suggest you change it to 49152 through65535.  If you need a larger range, continue downward from 49152, but leave65535 as your upper bound.  We will now list how to change the ephemeralport range on various operating systems.  As you'll see below, some systemsalready use our preferred range and will not need to be changed.  Someoperating systems also use two or more ranges, and to use the other ranges anapplication will have to be explicitly coded to choose the otherrange.  

This document was written for administrators using NcFTPdServer, so if the only reason you need to worry about ephemeral ports isbecause you want to run NcFTPd, then depending on the operating systemyou may not have to do anything since NcFTPd is aware of and alternatehigh-numbered ephemeral port ranges and will use them automatically.

What follows are operating system-specific instructions on changing theephemeral port range.


AIX

AIX uses the "no" command to set network options. AIX uses two separate ephemeral port ranges, one for TCP and UDP, and bothdefault to the values 32768 through 65535:

# /usr/sbin/no -a | fgrep ephemeral
        tcp_ephemeral_low = 32768
       tcp_ephemeral_high = 65535
        udp_ephemeral_low = 32768
       udp_ephemeral_high = 65535

The default range is sufficient, but you can change it using the nocommand.  Here is an example that sets the TCP ephemeral port range to49152 through 65535:

# /usr/sbin/no -o tcp_ephemeral_low=49152 -o tcp_ephemeral_high=65535

The options you set with no must be done each time the systemstarts up.  One way to do that is to edit /etc/rc.tcpip andinsert your no commands just before the script starts running theserver daemons.

 

BSD/OS

The default range is 49152 through 65535, as defined in /usr/include/netinet/in.h:

/*
* Local port number conventions:
* Ports < IPPORT_RESERVED are reserved for
* privileged processes (e.g. root).
* Ports >= IPPORT_RESERVED && < IPPORT_DYNAMIC
* are reserved for servers, not necessarily privileged.
* Ports >= IPPORT_DYNAMIC are available for
* dynamic port assignment.
*/
#define IPPORT_RESERVED 1024
#define IPPORT_DYNAMIC 49152
#define IPPORT_DYNAMIC_LAST 65535

There doesn't appear to be a runtime kernel setting for this (i.e. noavailable sysctl parameter to tweak), so to changethis you would need to recompile the kernel after changing thosedefinitions.  Since the default range is exactly what we recommend anyway,changing the range is not necessary.

 

FreeBSD

FreeBSD uses three ranges:

  1. The regular ephemeral port range
  2. An alternate ("high") ephemeral port range
  3. An alternate ("low") reserved port range, for use by programs using the rresvport() function.

These ranges are briefly documented in the system header file /usr/include/netinet/in.h:

/*
 * Local port number conventions:
 *
 * When a user does a bind(2) or connect(2) with a port number of zero,
 * a non-conflicting local port address is chosen.
 * The default range is IPPORT_RESERVED through
 * IPPORT_USERRESERVED, although that is settable by sysctl.
 *
 * A user may set the IPPROTO_IP option IP_PORTRANGE to change this
 * default assignment range.
 *
 * The value IP_PORTRANGE_DEFAULT causes the default behavior.
 *
 * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers
 * into the "high" range. These are reserved for client outbound connections
 * which do not want to be filtered by any firewalls.
 *
 * The value IP_PORTRANGE_LOW changes the range to the "low" are
 * that is (by convention) restricted to privileged processes. This
 * convention is based on "vouchsafe" principles only. It is only secure
 * if you trust the remote host to restrict these ports.
 *
 * The default range of ports and the high range can be changed by
 * sysctl(3). (net.inet.ip.port{hi,low}{first,last}_auto)
 *
 * Changing those values has bad security implications if you are
 * using a a stateless firewall that is allowing packets outside of that
 * range in order to allow transparent outgoing connections.
 *
 * Such a firewall configuration will generally depend on the use of these
 * default values. If you change them, you may find your Security
 * Administrator looking for you with a heavy object.
 *
 * For a slightly more orthodox text view on this:
 *
 * ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers
 *
 * port numbers are divided into three ranges:
 *
 * 0 - 1023 Well Known Ports
 * 1024 - 49151 Registered Ports
 * 49152 - 65535 Dynamic and/or Private Ports
 *
 */

/*
 * Ports < IPPORT_RESERVED are reserved for
 * privileged processes (e.g. root). (IP_PORTRANGE_LOW)
 * Ports > IPPORT_USERRESERVED are reserved
 * for servers, not necessarily privileged. (IP_PORTRANGE_DEFAULT)
 */
#define IPPORT_RESERVED 1024
#define IPPORT_USERRESERVED 5000

/*
 * Default local port range to use by setting IP_PORTRANGE_HIGH
 */
#define IPPORT_HIFIRSTAUTO 49152
#define IPPORT_HILASTAUTO 65535

/*
 * Scanning for a free reserved port return a value below IPPORT_RESERVED,
 * but higher than IPPORT_RESERVEDSTART. Traditionally the start value was
 * 512, but that conflicts with some well-known-services that firewalls may
 * have a fit if we use.
 */
#define IPPORT_RESERVEDSTART 600

Running the sysctl program shows the default values for theseranges:

/sbin/sysctl -a | fgrep net.inet.ip.portrange
net.inet.ip.portrange.lowfirst: 1023
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.first: 1024
net.inet.ip.portrange.last: 5000
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.hilast: 65535

To change this, edit /etc/sysctl.conf and add (or change existing)lines such as:

net.inet.ip.portrange.first=32768
net.inet.ip.portrange.last=49151
net.inet.ip.portrange.hifirst=49152
net.inet.ip.portrange.hilast=65535

This sets the regular ephemeral port range to use ports 32768 through 49151,the alternate ephemeral port range to 49152 through 65535, and leaves thereserved port range unchanged.  The system will need to be rebooted for thechanges to /etc/sysctl.conf to take effect (although you could justuse the sysctl program manually to make the changes immediately).

Note that NcFTPd uses the alternate range, whose default values areacceptable.  Therefore, no tuning is necessary unless you want to changethe behavior of other programs which may not explicitly attempt to use thealternate range like NcFTPd does.

 

HP-UX

HP-UX uses the "ndd" utility program to change tunableIP stack parameters.  The ephemeral ports on HP-UX can be tunedindividually for both TCP and UDP, so there are really two separate ephemeralport ranges.  HP-UX also provides options to change the privileged portrange (ports only processes running with superuser privileges can use).

The good news is that HP-UX uses our recommended port range (49152 through65535) so it is unlikely you will need to change the range from the defaultvalues.

The example below shows how to query the existing values for the TCPephemeral ports, and change the range to 50001 through 61000:

# /usr/bin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port
49152

65535
# /usr/bin/ndd -set /dev/tcp tcp_smallest_anon_port 50001
# /usr/bin/ndd -set /dev/tcp tcp_largest_anon_port 61000
# /usr/bin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port
50001

61000

Note that if you change the range values, you must do it each time the systemboots.  As we've mentioned, the default values are sufficient so you do notneed to change the range values, but if you decide to proceed, the preferred wayto do this for HP-UX is to edit the file /etc/rc.config.d/nddconf andadd entries.  For example, you might append these lines to your /etc/rc.config.d/nddconffile:

TRANSPORT_NAME[0]=tcp
NDD_NAME[0]=tcp_largest_anon_port
NDD_VALUE[0]=65535

TRANSPORT_NAME[1]=tcp
NDD_NAME[1]=tcp_smallest_anon_port
NDD_VALUE[1]=49152

If you do that, be sure that the entries are numbered accordingly.  Forexample, if there are 4 entries already present, you would see them numbered 0through 3 (i.e. TRANSPORT_NAME[3]=...).  In that case, theentries you append need to be numbered after the existing entries.

Another option instead of editing /etc/rc.config.d/nddconf youcould create a startup script to do the same thing.  Below is an example:

#!/bin/sh
#
# Copy me to /sbin/init.d/ephemports, then do
# "ln -s /sbin/init.d/ephemports /sbin/rc2.d/S341ephemports".
#
EPHEM_HI="65535"
EPHEM_LO="49152"
NDD=/usr/bin/ndd

if [ "$#" -eq 0 ] ; then arg="start" ; else arg="$1" ; fi
case "$arg" in
'start')
	;; # Fall through -- rest of script is the initialization code

'stop'|'start_msg'|'stop_msg')
	exit 0
	;;

'status')
	EPHEM_HI=`${NDD} /dev/udp udp_largest_anon_port`
	EPHEM_LO=`${NDD} /dev/udp udp_smallest_anon_port`
	echo "UDP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."
	EPHEM_HI=`${NDD} /dev/tcp tcp_largest_anon_port`
	EPHEM_LO=`${NDD} /dev/tcp tcp_smallest_anon_port`
	echo "TCP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."
	exit 0
	;;

*)
	echo "Usage: $0 { start | stop | status }"
	exit 1
	;;
esac

${NDD} -set /dev/udp udp_smallest_anon_port "${EPHEM_LO}"
${NDD} -set /dev/udp udp_largest_anon_port "${EPHEM_HI}"
${NDD} -set /dev/tcp tcp_smallest_anon_port "${EPHEM_LO}"
${NDD} -set /dev/tcp tcp_largest_anon_port "${EPHEM_HI}"

EPHEM_HI=`${NDD} /dev/udp udp_largest_anon_port`
EPHEM_LO=`${NDD} /dev/udp udp_smallest_anon_port`
echo "UDP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."
EPHEM_HI=`${NDD} /dev/tcp tcp_largest_anon_port`
EPHEM_LO=`${NDD} /dev/tcp tcp_smallest_anon_port`
echo "TCP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."

exit 0

For more information, see:

 

IRIX

Unfortunately IRIX does not seem to let you tune the ephemeral port range,and is statically set to 1024 through 65535.  Excerpted from /usr/include/netinet/in.h:

/*
 * Local port number conventions:
 * Ports < IPPORT_RESERVED are reserved for
 * privileged processes (e.g. root).
 * Ports > 5000 used to be reserved for non-root servers,
 * but this convention can no longer be used with large scale systems.
 * All well-known ports should be registered with the Internet Assigned
 * Numbers Authority.
 */
#define IPPORT_RESERVED         1024
#define IPPORT_MAXPORT          65535

There is also not an option listed for the systune program,although there are other IP and TCP/IP related options that can be set.

 

Linux

Linux allows you to view and change the ephemeral port range by simply usingthe file /proc/sys/net/ipv4/ip_local_port_range.  For example,this shows the default configuration on a kernel 2.2 system:

$ cat /proc/sys/net/ipv4/ip_local_port_range 
1024 4999

To change this to the preferred range, you could do (as superuser):

# echo "49152 65535" > /proc/sys/net/ipv4/ip_local_port_range 

Note that you would need to do this each time the system boots, so be sure toadd a line to a system startup script such as /etc/rc.local so yourrange is always used.

Also note that the Linux 2.4 kernel will default the range of 32768 through61000 if adequate kernel memory is available, so changing the range may not benecessary on newer Linux systems.

Finally, also note that you may be able to use the sysctlinterface to change the settings rather than using the /procfilesystem. The name of the sysctl parameter is "net.ipv4.ip_local_port_range". Edit the /etc/sysctl.conf file if you have it, or have a startupscript run the sysctl command manually if you want to change thisparameter using sysctl.

 

OpenBSD

OpenBSD uses the sysctl command to tune kernel parameters. The ephemeral ports on OpenBSD are actually two separate ranges, the regularrange, and the alternate "high" range.  Below is an exampleshowing how to use sysctl to view the current configuration of thesetwo ranges:

# /usr/sbin/sysctl net.inet.ip.portfirst net.inet.ip.portlast net.inet.ip.porthifirst net.inet.ip.porthilast
net.inet.ip.portfirst = 1024
net.inet.ip.portlast = 49151
net.inet.ip.porthifirst = 49152
net.inet.ip.porthilast = 65535

To change this, edit /etc/sysctl.conf and add (or change existing)lines such as:

net.inet.ip.portfirst=32768
net.inet.ip.portlast=49151
net.inet.ip.porthifirst=49152
net.inet.ip.porthilast=65535

This sets the regular ephemeral port range to use ports 32768 through 49151,and the alternate ephemeral port range to 49152 through 65535.  The systemwill need to be rebooted for the changes to /etc/sysctl.conf to takeeffect (although you could just use the sysctl program manually tomake the changes immediately).

Note that NcFTPd uses the alternate range, whose default values areacceptable.  Therefore, no tuning is necessary unless you want to changethe behavior of other programs which may not explicitly attempt to use thealternate range like NcFTPd does.

 

Solaris

Solaris uses the "ndd" utility program to change tunableIP stack parameters.  The ephemeral ports on Solaris can be tunedindividually for both TCP and UDP, so there are really two separate ephemeralport ranges.  Solaris also provides options to change the privileged portrange (ports only processes running with superuser privileges can use).

The good news is that Solaris by default provides a large range at the end ofthe port range (32768 through 65535, or the upper 50%) so it is unlikely youwill need to change the range from the default values.

The example below shows how to query the existing values for the TCPephemeral ports, and change the range to 49152 through 61000:

# /usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port
32768

65535
# /usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 49152
# /usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 61000
# /usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port
49152

61000

Note that if you change the range values, you must do it each time the systemboots.  Although we recommend that you just use the default range which issufficient, here is a sample script you can use to change the range at startup:

#!/sbin/sh
#
# Copy me to /etc/init.d/ephemports, then do
# "ln -s /etc/init.d/ephemports /etc/rc2.d/S70ephemports".
#
EPHEM_HI="65535"
EPHEM_LO="49152"

if [ "$#" -eq 0 ] ; then arg="start" ; else arg="$1" ; fi
case "$arg" in
'start')
	;; # Fall through -- rest of script is the initialization code

'stop')
	exit 0
	;;

'status')
	EPHEM_HI=`/usr/sbin/ndd /dev/udp udp_largest_anon_port`
	EPHEM_LO=`/usr/sbin/ndd /dev/udp udp_smallest_anon_port`
	echo "UDP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."
	EPHEM_HI=`/usr/sbin/ndd /dev/tcp tcp_largest_anon_port`
	EPHEM_LO=`/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port`
	echo "TCP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."
	exit 0
	;;

*)
	echo "Usage: $0 { start | stop | status }"
	exit 1
	;;
esac

/usr/sbin/ndd -set /dev/udp udp_smallest_anon_port "${EPHEM_LO}"
/usr/sbin/ndd -set /dev/udp udp_largest_anon_port "${EPHEM_HI}"
/usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port "${EPHEM_LO}"
/usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port "${EPHEM_HI}"

EPHEM_HI=`/usr/sbin/ndd /dev/udp udp_largest_anon_port`
EPHEM_LO=`/usr/sbin/ndd /dev/udp udp_smallest_anon_port`
echo "UDP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."
EPHEM_HI=`/usr/sbin/ndd /dev/tcp tcp_largest_anon_port`
EPHEM_LO=`/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port`
echo "TCP ephemeral port range is ${EPHEM_LO}..${EPHEM_HI}."

exit 0

For more information about tuning Solaris, refer to the following sources:

 

Tru64 UNIX

Compaq's Tru64 UNIX (formerly Digital UNIX and Digital OSF/1) uses thetraditional BSD range of 1024 through 4999 for its ephemeral port range. The following example uses the sysconfig command to query the currentrange:

# /sbin/sysconfig -q inet | fgrep ipport_userreserved
ipport_userreserved = 5000
ipport_userreserved_min = 1024

This next example shows how to use sysconfig to use our preferredephemeral port range:

# /sbin/sysconfig -r inet ipport_userreserved=65535 ipport_userreserved_min=49152
ipport_userreserved: reconfigured
ipport_userreserved_min: reconfigured

# /sbin/sysconfig -q inet | fgrep ipport_userreserved                         
ipport_userreserved = 65535
ipport_userreserved_min = 49152

Using the sysconfig command only applies the changes for thecurrent boot cycle.  To have the changes applied automatically each timethe system boots, you can either create a system startup script to run the sysconfigcommand, or better, use the sysconfigdb command to manage the /etc/sysconfigtabfile.  Here's an example:

/sbin/sysconfigdb -a -f /tmp/inet.stanza inet

The inet.stanza file we referenced in the example should look likethe following.  Make sure that your file has "inet:" by itself onthe first line, and the next two lines are preceded by a single tab character(do not use space characters).

inet:
    ipport_userreserved = 65535
    ipport_userreserved_min = 49152

See also:

 

Microsoft Windows

As of Windows Vista and Windows Server 2008, Windows now uses a large range (49152-65535)by default, according toMicrosoft Knowledgebase Article929851.That same article also shows how you can change the range if desired, but the defaultrange is now sufficient for most servers.

For older Windows operating systems (Windows XP and older),Windows uses the traditional BSD range of 1024 through 4999 for its ephemeralport range.  Unfortunately it appears that you can only set the upper boundof the ephemeral port range.  Here is information excerpted fromMicrosoft Knowledgebase Article196271:

  • Start Registry Editor (Regedt32.exe).
  • Locate the following key in the registry:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
  • On the Edit menu, click Add Value, and then add the following registry value:

    Value Name: MaxUserPort Data Type: REG_DWORD Value: 65534 <for example>

    Valid Range: 5000-65534 (decimal) Default: 0x1388 (5000 decimal)

    Description: This parameter controls the maximum port number used when an application requests any available user port from the system. Normally, ephemeral (that is, short-lived) ports are allocated between the values of 1024 and 5000 inclusive.
  • Quit Registry Editor.

Note: There is another relevant KB article(812873)which claims to allow you to set an exclusion range, which could mean thatyou could exclude ports 1024-9999 (for example) to have the ephemeralport range be 10000-65534. However, we have not been able to get this towork (as of October 2004).


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值